Skip to content

Commit

Permalink
Re-add changes from CesiumGS#8884
Browse files Browse the repository at this point in the history
  • Loading branch information
mramato authored and thw0rted committed Jun 1, 2020
1 parent 6b7322a commit c0c5c52
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 54 deletions.
5 changes: 3 additions & 2 deletions Source/Core/Event.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import defined from "./defined.js";
* exposed as a property for others to subscribe to.
*
* @alias Event
* @template Listener the function call signature for this event's listeners
* @constructor
* @example
* MyObject.prototype.myListener = function(arg1, arg2) {
Expand Down Expand Up @@ -46,7 +47,7 @@ Object.defineProperties(Event.prototype, {
* An optional scope can be provided to serve as the <code>this</code> pointer
* in which the function will execute.
*
* @param {Function} listener The function to be executed when the event is raised.
* @param {Listener} listener The function to be executed when the event is raised.
* @param {Object} [scope] An optional object scope to serve as the <code>this</code>
* pointer in which the listener function will execute.
* @returns {Event.RemoveCallback} A function that will remove this event listener when invoked.
Expand All @@ -71,7 +72,7 @@ Event.prototype.addEventListener = function (listener, scope) {
/**
* Unregisters a previously registered callback.
*
* @param {Function} listener The function to be unregistered.
* @param {Listener} listener The function to be unregistered.
* @param {Object} [scope] The scope that was originally passed to addEventListener.
* @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event.
*
Expand Down
34 changes: 24 additions & 10 deletions Source/Core/Resource.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,21 +212,35 @@ function combineQueryParameters(q1, q2, preserveQueryParameters) {
return result;
}

/** @typedef {string | number | boolean} QueryValue */
/**
* @typedef {Object.<string, QueryValue | QueryValue[] | undefined>} Resource.QueryParameters
* QueryParameters must be an object whose keys are parameter names and whose
* values are a primitive (string, number, boolean) or an array thereof.
* */

/**
* @typedef {Object} Resource.ConstructorOptions
*
* Initialization options for the Resource constructor
*
* @property {String} url The url of the resource.
* @property {Resource.QueryParameters} [queryParameters] An object containing query parameters that will be sent when retrieving the resource.
* @property {Object} [templateValues] Key/Value pairs that are used to replace template values (eg. {x}).
* @property {Object} [headers={}] Additional HTTP headers that will be sent.
* @property {Proxy} [proxy] A proxy to be used when loading the resource.
* @property {Resource.RetryCallback} [retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried.
* @property {Number} [retryAttempts=0] The number of times the retryCallback should be called before giving up.
* @property {Request} [request] A Request object that will be used. Intended for internal use only.
*/

/**
* A resource that includes the location and any other parameters we need to retrieve it or create derived resources. It also provides the ability to retry requests.
*
* @alias Resource
* @constructor
*
* @param {String|Object} options A url or an object with the following properties
* @param {String} options.url The url of the resource.
* @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource.
* @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}).
* @param {Object} [options.headers={}] Additional HTTP headers that will be sent.
* @param {Proxy} [options.proxy] A proxy to be used when loading the resource.
* @param {Resource.RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried.
* @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up.
* @param {Request} [options.request] A Request object that will be used. Intended for internal use only.
* @param {String|Resource.ConstructorOptions} options A url or an object describing initialization options
*
* @example
* function refreshTokenRetryCallback(resource, error) {
Expand Down Expand Up @@ -564,7 +578,7 @@ Resource.prototype.getUrlComponent = function (query, proxy) {
* Combines the specified object and the existing query parameters. This allows you to add many parameters at once,
* as opposed to adding them one at a time to the queryParameters property. If a value is already set, it will be replaced with the new value.
*
* @param {Object} params The query parameters
* @param {Resource.QueryParameters} params The query parameters
* @param {Boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined.
*/
Resource.prototype.setQueryParameters = function (params, useAsDefault) {
Expand Down
4 changes: 2 additions & 2 deletions Source/DataSources/DataSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@ Object.defineProperties(DataSource.prototype, {
/**
* Gets an event that will be raised if an error is encountered during processing.
* @memberof DataSource.prototype
* @type {Event}
* @type {Event<function(this, RequestErrorEvent)>}
*/
errorEvent: {
get: DeveloperError.throwInstantiationError,
},
/**
* Gets an event that will be raised when the value of isLoading changes.
* @memberof DataSource.prototype
* @type {Event}
* @type {Event<function(this, boolean)>}
*/
loadingEvent: {
get: DeveloperError.throwInstantiationError,
Expand Down
5 changes: 3 additions & 2 deletions Source/DataSources/EntityCluster.js
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ Object.defineProperties(EntityCluster.prototype, {
/**
* Gets the event that will be raised when a new cluster will be displayed. The signature of the event listener is {@link EntityCluster.newClusterCallback}.
* @memberof EntityCluster.prototype
* @type {Event}
* @type {Event<EntityCluster.newClusterCallback>}
*/
clusterEvent: {
get: function () {
Expand Down Expand Up @@ -963,7 +963,8 @@ EntityCluster.prototype.destroy = function () {
* @callback EntityCluster.newClusterCallback
*
* @param {Entity[]} clusteredEntities An array of the entities contained in the cluster.
* @param {Object} cluster An object containing billboard, label, and point properties. The values are the same as
* @param {{billboard: Billboard, label: Label, point: PointPrimitive}} cluster An object
* containing billboard, label, and point properties. The values are the same as
* billboard, label and point entities, but must be the values of the ConstantProperty.
*
* @example
Expand Down
7 changes: 1 addition & 6 deletions Source/DataSources/PropertyBag.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ import Property from "./Property.js";
/**
* A {@link Property} whose value is a key-value mapping of property names to the computed value of other properties.
*
* @alias PropertyBag
* @constructor
* @implements {DictionaryLike}
*
* @param {Object} [value] An object, containing key-value mapping of property names to properties.
* @param {Function} [createPropertyCallback] A function that will be called when the value of any of the properties in value are not a Property.
* @typedef {PropertyBagType}
*/
function PropertyBag(value, createPropertyCallback) {
this._propertyNames = [];
Expand Down
76 changes: 51 additions & 25 deletions Source/DataSources/exportKml.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,33 @@ IdManager.prototype.get = function (id) {

return id.toString() + "-" + ++ids[id];
};
/**
* @variation 2 KML return
* @param {Object} options An object with the following properties:
* @param {EntityCollection} options.entities The EntityCollection to export as KML.
* @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for the output file.
* @param {exportKmlModelCallback} [options.modelCallback] A callback that will be called with a {@link ModelGraphics} instance and should return the URI to use in the KML. Required if a model exists in the entity collection.
* @param {JulianDate} [options.time=entities.computeAvailability().start] The time value to use to get properties that are not time varying in KML.
* @param {TimeInterval} [options.defaultAvailability=entities.computeAvailability()] The interval that will be sampled if an entity doesn't have an availability.
* @param {Number} [options.sampleDuration=60] The number of seconds to sample properties that are varying in KML.
* @param {false} [options.kmz=false] If false or unset, returns the KML file and referenced resources individually
*
* @returns {Promise<exportKmlResultKml>} A promise that resolved to an object containing the KML string and a dictionary of external file Blobs
*
* @example
* Cesium.exportKml({
* entities: entityCollection
* })
* .then(function(result) {
* // The XML string is in result.kml
*
* var externalFiles = result.externalFiles
* for(var file in externalFiles) {
* // file is the name of the file used in the KML document as the href
* // externalFiles[file] is a Blob with the contents of the file
* }
* });
*/

/**
* @typedef exportKmlResultKml
Expand All @@ -236,44 +263,43 @@ IdManager.prototype.get = function (id) {
*/

/**
* Exports an EntityCollection as a KML document. Only Point, Billboard, Model, Path, Polygon, Polyline geometries
* will be exported. Note that there is not a 1 to 1 mapping of Entity properties to KML Feature properties. For
* example, entity properties that are time dynamic but cannot be dynamic in KML are exported with their values at
* options.time or the beginning of the EntityCollection's time interval if not specified. For time-dynamic properties
* that are supported in KML, we use the samples if it is a {@link SampledProperty} otherwise we sample the value using
* the options.sampleDuration. Point, Billboard, Model and Path geometries with time-dynamic positions will be exported
* as gx:Track Features. Not all Materials are representable in KML, so for more advanced Materials just the primary
* color is used. Canvas objects are exported as PNG images.
* Exports an EntityCollection as a KML document or KMZ archive.
*
* Only Point, Billboard, Model, Path, Polygon, Polyline geometries will be exported.
* Note that there is not a 1 to 1 mapping of Entity properties to KML Feature
* properties. For example, entity properties that are time dynamic but cannot
* be dynamic in KML are exported with their values at `options.time` or the
* beginning of the EntityCollection's time interval if not specified. For
* time-dynamic properties that are supported in KML, we use the samples if it
* is a {@link SampledProperty}, otherwise we sample the value using the
* `options.sampleDuration`. Point, Billboard, Model and Path geometries with
* time-dynamic positions will be exported as gx:Track Features.
*
* @function exportKml
* Not all Materials are representable in KML, so for more advanced Materials
* just the primary color is used. Canvas objects are exported as PNG images.
*
* @variation 1 KMZ return
* @param {Object} options An object with the following properties:
* @param {EntityCollection} options.entities The EntityCollection to export as KML.
* @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for the output file.
* @param {exportKmlModelCallback} [options.modelCallback] A callback that will be called with a {@link ModelGraphics} instance and should return the URI to use in the KML. Required if a model exists in the entity collection.
* @param {JulianDate} [options.time=entities.computeAvailability().start] The time value to use to get properties that are not time varying in KML.
* @param {TimeInterval} [options.defaultAvailability=entities.computeAvailability()] The interval that will be sampled if an entity doesn't have an availability.
* @param {Number} [options.sampleDuration=60] The number of seconds to sample properties that are varying in KML.
* @param {Boolean} [options.kmz=false] If true KML and external files will be compressed into a kmz file.
* @param {true} options.kmz If true, KML and external files will be compressed into a single KMZ file.
*
* @returns {Promise<exportKmlResultKmz>} A promise that resolves to a KMZ file as a Blob.
*
* @returns {Promise<exportKmlResultKml|exportKmlResultKmz>} A promise that resolved to an object containing the KML string and a dictionary of external file blobs, or a kmz file as a blob if options.kmz is true.
* @demo {@link https://sandcastle.cesium.com/index.html?src=Export%20KML.html|Cesium Sandcastle KML Export Demo}
* @example
* Cesium.exportKml({
* entities: entityCollection
* })
* .then(function(result) {
* // The XML string is in result.kml
*
* var externalFiles = result.externalFiles
* for(var file in externalFiles) {
* // file is the name of the file used in the KML document as the href
* // externalFiles[file] is a blob with the contents of the file
* }
* });
*
*/
function exportKml(options) {
* entities: entityCollection,
* options: { kmz: true }
* })
* .then(function(result) {
* downloadFile(result.kmz);
* });
*/ function exportKml(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
var entities = options.entities;
var kmz = defaultValue(options.kmz, false);
Expand Down
28 changes: 21 additions & 7 deletions gulpfile.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -1481,10 +1481,9 @@ function createCesiumJs() {

function createTypeScriptDefinitions() {
// Run jsdoc with tsd-jsdoc to generate an initial Cesium.d.ts file.
child_process.execSync(
"node_modules/.bin/jsdoc --configure Tools/jsdoc/ts-conf.json",
{ stdio: "inherit" }
);
child_process.execSync("npx jsdoc --configure Tools/jsdoc/ts-conf.json", {
stdio: "inherit",
});

var source = fs.readFileSync("Source/Cesium.d.ts").toString();

Expand Down Expand Up @@ -1568,6 +1567,11 @@ function createTypeScriptDefinitions() {
.replace(/<String>/gm, "<string>")
.replace(/<Boolean>/gm, "<boolean>")
.replace(/<Object>/gm, "<object>")
// This is an ugly hack but @template doesn't actually seem to work
.replace(
/export class Event {/gm,
"export class Event<Listener extends Function = Function> {"
)
.replace(
/= "WebGLConstants\.(.+)"/gm,
(match, p1) => `= WebGLConstants.${p1}`
Expand All @@ -1580,9 +1584,19 @@ function createTypeScriptDefinitions() {
/**
* Private interfaces to support PropertyBag being a dictionary-like object.
*/
interface DictionaryLike {
[index: string]: any;
interface PropertyDictionary {
[key: string]: Property | undefined;
}
class PropertyBagBase {
readonly propertyNames: string[];
constructor(value?: object, createPropertyCallback?: Function);
addProperty(propertyName: string, value?: any, createPropertyCallback?: Function): void;
hasProperty(propertyName: string): boolean;
merge(source: Object, createPropertyCallback?: Function): void;
removeProperty(propertyName: string): void;
}
/** This has to be in the workaround section because JSDoc doesn't support Intersection Types */
type PropertyBagType = PropertyDictionary & Property & PropertyBagBase;
${source}
}
Expand All @@ -1608,7 +1622,7 @@ ${source}
fs.writeFileSync("Source/Cesium.d.ts", source);

// Use tsc to compile it and make sure it is valid
child_process.execSync("node_modules/.bin/tsc -p Tools/jsdoc/tsconfig.json", {
child_process.execSync("npx tsc -p Tools/jsdoc/tsconfig.json", {
stdio: "inherit",
});

Expand Down

0 comments on commit c0c5c52

Please sign in to comment.