| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064 | import ArcType from "../Core/ArcType.js";import Cartesian3 from "../Core/Cartesian3.js";import Color from "../Core/Color.js";import createGuid from "../Core/createGuid.js";import Credit from "../Core/Credit.js";import defaultValue from "../Core/defaultValue.js";import defined from "../Core/defined.js";import DeveloperError from "../Core/DeveloperError.js";import Event from "../Core/Event.js";import getFilenameFromUri from "../Core/getFilenameFromUri.js";import PinBuilder from "../Core/PinBuilder.js";import PolygonHierarchy from "../Core/PolygonHierarchy.js";import Resource from "../Core/Resource.js";import RuntimeError from "../Core/RuntimeError.js";import HeightReference from "../Scene/HeightReference.js";import VerticalOrigin from "../Scene/VerticalOrigin.js";import topojson from "../ThirdParty/topojson.js";import BillboardGraphics from "./BillboardGraphics.js";import CallbackProperty from "./CallbackProperty.js";import ColorMaterialProperty from "./ColorMaterialProperty.js";import ConstantPositionProperty from "./ConstantPositionProperty.js";import ConstantProperty from "./ConstantProperty.js";import DataSource from "./DataSource.js";import EntityCluster from "./EntityCluster.js";import EntityCollection from "./EntityCollection.js";import PolygonGraphics from "./PolygonGraphics.js";import PolylineGraphics from "./PolylineGraphics.js";function defaultCrsFunction(coordinates) {  return Cartesian3.fromDegrees(coordinates[0], coordinates[1], coordinates[2]);}const crsNames = {  "urn:ogc:def:crs:OGC:1.3:CRS84": defaultCrsFunction,  "EPSG:4326": defaultCrsFunction,  "urn:ogc:def:crs:EPSG::4326": defaultCrsFunction,};const crsLinkHrefs = {};const crsLinkTypes = {};let defaultMarkerSize = 48;let defaultMarkerSymbol;let defaultMarkerColor = Color.ROYALBLUE;let defaultStroke = Color.YELLOW;let defaultStrokeWidth = 2;let defaultFill = Color.fromBytes(255, 255, 0, 100);let defaultClampToGround = false;const sizes = {  small: 24,  medium: 48,  large: 64,};const simpleStyleIdentifiers = [  "title",  "description", //  "marker-size",  "marker-symbol",  "marker-color",  "stroke", //  "stroke-opacity",  "stroke-width",  "fill",  "fill-opacity",];function defaultDescribe(properties, nameProperty) {  let html = "";  for (const key in properties) {    if (properties.hasOwnProperty(key)) {      if (key === nameProperty || simpleStyleIdentifiers.indexOf(key) !== -1) {        continue;      }      const value = properties[key];      if (defined(value)) {        if (typeof value === "object") {          html += `<tr><th>${key}</th><td>${defaultDescribe(value)}</td></tr>`;        } else {          html += `<tr><th>${key}</th><td>${value}</td></tr>`;        }      }    }  }  if (html.length > 0) {    html = `<table class="cesium-infoBox-defaultTable"><tbody>${html}</tbody></table>`;  }  return html;}function createDescriptionCallback(describe, properties, nameProperty) {  let description;  return function (time, result) {    if (!defined(description)) {      description = describe(properties, nameProperty);    }    return description;  };}function defaultDescribeProperty(properties, nameProperty) {  return new CallbackProperty(    createDescriptionCallback(defaultDescribe, properties, nameProperty),    true  );}//GeoJSON specifies only the Feature object has a usable id property//But since "multi" geometries create multiple entity,//we can't use it for them either.function createObject(geoJson, entityCollection, describe) {  let id = geoJson.id;  if (!defined(id) || geoJson.type !== "Feature") {    id = createGuid();  } else {    let i = 2;    let finalId = id;    while (defined(entityCollection.getById(finalId))) {      finalId = `${id}_${i}`;      i++;    }    id = finalId;  }  const entity = entityCollection.getOrCreateEntity(id);  const properties = geoJson.properties;  if (defined(properties)) {    entity.properties = properties;    let nameProperty;    //Check for the simplestyle specified name first.    const name = properties.title;    if (defined(name)) {      entity.name = name;      nameProperty = "title";    } else {      //Else, find the name by selecting an appropriate property.      //The name will be obtained based on this order:      //1) The first case-insensitive property with the name 'title',      //2) The first case-insensitive property with the name 'name',      //3) The first property containing the word 'title'.      //4) The first property containing the word 'name',      let namePropertyPrecedence = Number.MAX_VALUE;      for (const key in properties) {        if (properties.hasOwnProperty(key) && properties[key]) {          const lowerKey = key.toLowerCase();          if (namePropertyPrecedence > 1 && lowerKey === "title") {            namePropertyPrecedence = 1;            nameProperty = key;            break;          } else if (namePropertyPrecedence > 2 && lowerKey === "name") {            namePropertyPrecedence = 2;            nameProperty = key;          } else if (namePropertyPrecedence > 3 && /title/i.test(key)) {            namePropertyPrecedence = 3;            nameProperty = key;          } else if (namePropertyPrecedence > 4 && /name/i.test(key)) {            namePropertyPrecedence = 4;            nameProperty = key;          }        }      }      if (defined(nameProperty)) {        entity.name = properties[nameProperty];      }    }    const description = properties.description;    if (description !== null) {      entity.description = !defined(description)        ? describe(properties, nameProperty)        : new ConstantProperty(description);    }  }  return entity;}function coordinatesArrayToCartesianArray(coordinates, crsFunction) {  const positions = new Array(coordinates.length);  for (let i = 0; i < coordinates.length; i++) {    positions[i] = crsFunction(coordinates[i]);  }  return positions;}const geoJsonObjectTypes = {  Feature: processFeature,  FeatureCollection: processFeatureCollection,  GeometryCollection: processGeometryCollection,  LineString: processLineString,  MultiLineString: processMultiLineString,  MultiPoint: processMultiPoint,  MultiPolygon: processMultiPolygon,  Point: processPoint,  Polygon: processPolygon,  Topology: processTopology,};const geometryTypes = {  GeometryCollection: processGeometryCollection,  LineString: processLineString,  MultiLineString: processMultiLineString,  MultiPoint: processMultiPoint,  MultiPolygon: processMultiPolygon,  Point: processPoint,  Polygon: processPolygon,  Topology: processTopology,};// GeoJSON processing functionsfunction processFeature(dataSource, feature, notUsed, crsFunction, options) {  if (feature.geometry === null) {    //Null geometry is allowed, so just create an empty entity instance for it.    createObject(feature, dataSource._entityCollection, options.describe);    return;  }  if (!defined(feature.geometry)) {    throw new RuntimeError("feature.geometry is required.");  }  const geometryType = feature.geometry.type;  const geometryHandler = geometryTypes[geometryType];  if (!defined(geometryHandler)) {    throw new RuntimeError(`Unknown geometry type: ${geometryType}`);  }  geometryHandler(dataSource, feature, feature.geometry, crsFunction, options);}function processFeatureCollection(  dataSource,  featureCollection,  notUsed,  crsFunction,  options) {  const features = featureCollection.features;  for (let i = 0, len = features.length; i < len; i++) {    processFeature(dataSource, features[i], undefined, crsFunction, options);  }}function processGeometryCollection(  dataSource,  geoJson,  geometryCollection,  crsFunction,  options) {  const geometries = geometryCollection.geometries;  for (let i = 0, len = geometries.length; i < len; i++) {    const geometry = geometries[i];    const geometryType = geometry.type;    const geometryHandler = geometryTypes[geometryType];    if (!defined(geometryHandler)) {      throw new RuntimeError(`Unknown geometry type: ${geometryType}`);    }    geometryHandler(dataSource, geoJson, geometry, crsFunction, options);  }}function createPoint(dataSource, geoJson, crsFunction, coordinates, options) {  let symbol = options.markerSymbol;  let color = options.markerColor;  let size = options.markerSize;  const properties = geoJson.properties;  if (defined(properties)) {    const cssColor = properties["marker-color"];    if (defined(cssColor)) {      color = Color.fromCssColorString(cssColor);    }    size = defaultValue(sizes[properties["marker-size"]], size);    const markerSymbol = properties["marker-symbol"];    if (defined(markerSymbol)) {      symbol = markerSymbol;    }  }  let canvasOrPromise;  if (defined(symbol)) {    if (symbol.length === 1) {      canvasOrPromise = dataSource._pinBuilder.fromText(        symbol.toUpperCase(),        color,        size      );    } else {      canvasOrPromise = dataSource._pinBuilder.fromMakiIconId(        symbol,        color,        size      );    }  } else {    canvasOrPromise = dataSource._pinBuilder.fromColor(color, size);  }  const billboard = new BillboardGraphics();  billboard.verticalOrigin = new ConstantProperty(VerticalOrigin.BOTTOM);  // Clamp to ground if there isn't a height specified  if (coordinates.length === 2 && options.clampToGround) {    billboard.heightReference = HeightReference.CLAMP_TO_GROUND;  }  const entity = createObject(    geoJson,    dataSource._entityCollection,    options.describe  );  entity.billboard = billboard;  entity.position = new ConstantPositionProperty(crsFunction(coordinates));  const promise = Promise.resolve(canvasOrPromise)    .then(function (image) {      billboard.image = new ConstantProperty(image);    })    .catch(function () {      billboard.image = new ConstantProperty(        dataSource._pinBuilder.fromColor(color, size)      );    });  dataSource._promises.push(promise);}function processPoint(dataSource, geoJson, geometry, crsFunction, options) {  createPoint(dataSource, geoJson, crsFunction, geometry.coordinates, options);}function processMultiPoint(  dataSource,  geoJson,  geometry,  crsFunction,  options) {  const coordinates = geometry.coordinates;  for (let i = 0; i < coordinates.length; i++) {    createPoint(dataSource, geoJson, crsFunction, coordinates[i], options);  }}function createLineString(  dataSource,  geoJson,  crsFunction,  coordinates,  options) {  let material = options.strokeMaterialProperty;  let widthProperty = options.strokeWidthProperty;  const properties = geoJson.properties;  if (defined(properties)) {    const width = properties["stroke-width"];    if (defined(width)) {      widthProperty = new ConstantProperty(width);    }    let color;    const stroke = properties.stroke;    if (defined(stroke)) {      color = Color.fromCssColorString(stroke);    }    const opacity = properties["stroke-opacity"];    if (defined(opacity) && opacity !== 1.0) {      if (!defined(color)) {        color = material.color.getValue().clone();      }      color.alpha = opacity;    }    if (defined(color)) {      material = new ColorMaterialProperty(color);    }  }  const entity = createObject(    geoJson,    dataSource._entityCollection,    options.describe  );  const polylineGraphics = new PolylineGraphics();  entity.polyline = polylineGraphics;  polylineGraphics.clampToGround = options.clampToGround;  polylineGraphics.material = material;  polylineGraphics.width = widthProperty;  polylineGraphics.positions = new ConstantProperty(    coordinatesArrayToCartesianArray(coordinates, crsFunction)  );  polylineGraphics.arcType = ArcType.RHUMB;}function processLineString(  dataSource,  geoJson,  geometry,  crsFunction,  options) {  createLineString(    dataSource,    geoJson,    crsFunction,    geometry.coordinates,    options  );}function processMultiLineString(  dataSource,  geoJson,  geometry,  crsFunction,  options) {  const lineStrings = geometry.coordinates;  for (let i = 0; i < lineStrings.length; i++) {    createLineString(dataSource, geoJson, crsFunction, lineStrings[i], options);  }}function createPolygon(dataSource, geoJson, crsFunction, coordinates, options) {  if (coordinates.length === 0 || coordinates[0].length === 0) {    return;  }  let outlineColorProperty = options.strokeMaterialProperty.color;  let material = options.fillMaterialProperty;  let widthProperty = options.strokeWidthProperty;  const properties = geoJson.properties;  if (defined(properties)) {    const width = properties["stroke-width"];    if (defined(width)) {      widthProperty = new ConstantProperty(width);    }    let color;    const stroke = properties.stroke;    if (defined(stroke)) {      color = Color.fromCssColorString(stroke);    }    let opacity = properties["stroke-opacity"];    if (defined(opacity) && opacity !== 1.0) {      if (!defined(color)) {        color = outlineColorProperty.getValue().clone();      }      color.alpha = opacity;    }    if (defined(color)) {      outlineColorProperty = new ConstantProperty(color);    }    let fillColor;    const fill = properties.fill;    const materialColor = material.color.getValue();    if (defined(fill)) {      fillColor = Color.fromCssColorString(fill);      fillColor.alpha = materialColor.alpha;    }    opacity = properties["fill-opacity"];    if (defined(opacity) && opacity !== materialColor.alpha) {      if (!defined(fillColor)) {        fillColor = materialColor.clone();      }      fillColor.alpha = opacity;    }    if (defined(fillColor)) {      material = new ColorMaterialProperty(fillColor);    }  }  const polygon = new PolygonGraphics();  polygon.outline = new ConstantProperty(true);  polygon.outlineColor = outlineColorProperty;  polygon.outlineWidth = widthProperty;  polygon.material = material;  polygon.arcType = ArcType.RHUMB;  const holes = [];  for (let i = 1, len = coordinates.length; i < len; i++) {    holes.push(      new PolygonHierarchy(        coordinatesArrayToCartesianArray(coordinates[i], crsFunction)      )    );  }  const positions = coordinates[0];  polygon.hierarchy = new ConstantProperty(    new PolygonHierarchy(      coordinatesArrayToCartesianArray(positions, crsFunction),      holes    )  );  if (positions[0].length > 2) {    polygon.perPositionHeight = new ConstantProperty(true);  } else if (!options.clampToGround) {    polygon.height = 0;  }  const entity = createObject(    geoJson,    dataSource._entityCollection,    options.describe  );  entity.polygon = polygon;}function processPolygon(dataSource, geoJson, geometry, crsFunction, options) {  createPolygon(    dataSource,    geoJson,    crsFunction,    geometry.coordinates,    options  );}function processMultiPolygon(  dataSource,  geoJson,  geometry,  crsFunction,  options) {  const polygons = geometry.coordinates;  for (let i = 0; i < polygons.length; i++) {    createPolygon(dataSource, geoJson, crsFunction, polygons[i], options);  }}function processTopology(dataSource, geoJson, geometry, crsFunction, options) {  for (const property in geometry.objects) {    if (geometry.objects.hasOwnProperty(property)) {      const feature = topojson.feature(geometry, geometry.objects[property]);      const typeHandler = geoJsonObjectTypes[feature.type];      typeHandler(dataSource, feature, feature, crsFunction, options);    }  }}/** * @typedef {Object} GeoJsonDataSource.LoadOptions * * Initialization options for the <code>load</code> method. * * @property {String} [sourceUri] Overrides the url to use for resolving relative links. * @property {GeoJsonDataSource.describe} [describe=GeoJsonDataSource.defaultDescribeProperty] A function which returns a Property object (or just a string). * @property {Number} [markerSize=GeoJsonDataSource.markerSize] The default size of the map pin created for each point, in pixels. * @property {String} [markerSymbol=GeoJsonDataSource.markerSymbol] The default symbol of the map pin created for each point. * @property {Color} [markerColor=GeoJsonDataSource.markerColor] The default color of the map pin created for each point. * @property {Color} [stroke=GeoJsonDataSource.stroke] The default color of polylines and polygon outlines. * @property {Number} [strokeWidth=GeoJsonDataSource.strokeWidth] The default width of polylines and polygon outlines. * @property {Color} [fill=GeoJsonDataSource.fill] The default color for polygon interiors. * @property {Boolean} [clampToGround=GeoJsonDataSource.clampToGround] true if we want the geometry features (polygons or linestrings) clamped to the ground. * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas. *//** * A {@link DataSource} which processes both * {@link http://www.geojson.org/|GeoJSON} and {@link https://github.com/mbostock/topojson|TopoJSON} data. * {@link https://github.com/mapbox/simplestyle-spec|simplestyle-spec} properties will also be used if they * are present. * * @alias GeoJsonDataSource * @constructor * * @param {String} [name] The name of this data source.  If undefined, a name will be taken from *                        the name of the GeoJSON file. * * @demo {@link https://sandcastle.cesium.com/index.html?src=GeoJSON%20and%20TopoJSON.html|Cesium Sandcastle GeoJSON and TopoJSON Demo} * @demo {@link https://sandcastle.cesium.com/index.html?src=GeoJSON%20simplestyle.html|Cesium Sandcastle GeoJSON simplestyle Demo} * * @example * const viewer = new Cesium.Viewer('cesiumContainer'); * viewer.dataSources.add(Cesium.GeoJsonDataSource.load('../../SampleData/ne_10m_us_states.topojson', { *   stroke: Cesium.Color.HOTPINK, *   fill: Cesium.Color.PINK, *   strokeWidth: 3, *   markerSymbol: '?' * })); */function GeoJsonDataSource(name) {  this._name = name;  this._changed = new Event();  this._error = new Event();  this._isLoading = false;  this._loading = new Event();  this._entityCollection = new EntityCollection(this);  this._promises = [];  this._pinBuilder = new PinBuilder();  this._entityCluster = new EntityCluster();  this._credit = undefined;  this._resourceCredits = [];}/** * Creates a Promise to a new instance loaded with the provided GeoJSON or TopoJSON data. * * @param {Resource|String|Object} data A url, GeoJSON object, or TopoJSON object to be loaded. * @param {GeoJsonDataSource.LoadOptions} [options] An object specifying configuration options * * @returns {Promise.<GeoJsonDataSource>} A promise that will resolve when the data is loaded. */GeoJsonDataSource.load = function (data, options) {  return new GeoJsonDataSource().load(data, options);};Object.defineProperties(GeoJsonDataSource, {  /**   * Gets or sets the default size of the map pin created for each point, in pixels.   * @memberof GeoJsonDataSource   * @type {Number}   * @default 48   */  markerSize: {    get: function () {      return defaultMarkerSize;    },    set: function (value) {      defaultMarkerSize = value;    },  },  /**   * Gets or sets the default symbol of the map pin created for each point.   * This can be any valid {@link http://mapbox.com/maki/|Maki} identifier, any single character,   * or blank if no symbol is to be used.   * @memberof GeoJsonDataSource   * @type {String}   */  markerSymbol: {    get: function () {      return defaultMarkerSymbol;    },    set: function (value) {      defaultMarkerSymbol = value;    },  },  /**   * Gets or sets the default color of the map pin created for each point.   * @memberof GeoJsonDataSource   * @type {Color}   * @default Color.ROYALBLUE   */  markerColor: {    get: function () {      return defaultMarkerColor;    },    set: function (value) {      defaultMarkerColor = value;    },  },  /**   * Gets or sets the default color of polylines and polygon outlines.   * @memberof GeoJsonDataSource   * @type {Color}   * @default Color.BLACK   */  stroke: {    get: function () {      return defaultStroke;    },    set: function (value) {      defaultStroke = value;    },  },  /**   * Gets or sets the default width of polylines and polygon outlines.   * @memberof GeoJsonDataSource   * @type {Number}   * @default 2.0   */  strokeWidth: {    get: function () {      return defaultStrokeWidth;    },    set: function (value) {      defaultStrokeWidth = value;    },  },  /**   * Gets or sets default color for polygon interiors.   * @memberof GeoJsonDataSource   * @type {Color}   * @default Color.YELLOW   */  fill: {    get: function () {      return defaultFill;    },    set: function (value) {      defaultFill = value;    },  },  /**   * Gets or sets default of whether to clamp to the ground.   * @memberof GeoJsonDataSource   * @type {Boolean}   * @default false   */  clampToGround: {    get: function () {      return defaultClampToGround;    },    set: function (value) {      defaultClampToGround = value;    },  },  /**   * Gets an object that maps the name of a crs to a callback function which takes a GeoJSON coordinate   * and transforms it into a WGS84 Earth-fixed Cartesian.  Older versions of GeoJSON which   * supported the EPSG type can be added to this list as well, by specifying the complete EPSG name,   * for example 'EPSG:4326'.   * @memberof GeoJsonDataSource   * @type {Object}   */  crsNames: {    get: function () {      return crsNames;    },  },  /**   * Gets an object that maps the href property of a crs link to a callback function   * which takes the crs properties object and returns a Promise that resolves   * to a function that takes a GeoJSON coordinate and transforms it into a WGS84 Earth-fixed Cartesian.   * Items in this object take precedence over those defined in <code>crsLinkHrefs</code>, assuming   * the link has a type specified.   * @memberof GeoJsonDataSource   * @type {Object}   */  crsLinkHrefs: {    get: function () {      return crsLinkHrefs;    },  },  /**   * Gets an object that maps the type property of a crs link to a callback function   * which takes the crs properties object and returns a Promise that resolves   * to a function that takes a GeoJSON coordinate and transforms it into a WGS84 Earth-fixed Cartesian.   * Items in <code>crsLinkHrefs</code> take precedence over this object.   * @memberof GeoJsonDataSource   * @type {Object}   */  crsLinkTypes: {    get: function () {      return crsLinkTypes;    },  },});Object.defineProperties(GeoJsonDataSource.prototype, {  /**   * Gets or sets a human-readable name for this instance.   * @memberof GeoJsonDataSource.prototype   * @type {String}   */  name: {    get: function () {      return this._name;    },    set: function (value) {      if (this._name !== value) {        this._name = value;        this._changed.raiseEvent(this);      }    },  },  /**   * This DataSource only defines static data, therefore this property is always undefined.   * @memberof GeoJsonDataSource.prototype   * @type {DataSourceClock}   */  clock: {    value: undefined,    writable: false,  },  /**   * Gets the collection of {@link Entity} instances.   * @memberof GeoJsonDataSource.prototype   * @type {EntityCollection}   */  entities: {    get: function () {      return this._entityCollection;    },  },  /**   * Gets a value indicating if the data source is currently loading data.   * @memberof GeoJsonDataSource.prototype   * @type {Boolean}   */  isLoading: {    get: function () {      return this._isLoading;    },  },  /**   * Gets an event that will be raised when the underlying data changes.   * @memberof GeoJsonDataSource.prototype   * @type {Event}   */  changedEvent: {    get: function () {      return this._changed;    },  },  /**   * Gets an event that will be raised if an error is encountered during processing.   * @memberof GeoJsonDataSource.prototype   * @type {Event}   */  errorEvent: {    get: function () {      return this._error;    },  },  /**   * Gets an event that will be raised when the data source either starts or stops loading.   * @memberof GeoJsonDataSource.prototype   * @type {Event}   */  loadingEvent: {    get: function () {      return this._loading;    },  },  /**   * Gets whether or not this data source should be displayed.   * @memberof GeoJsonDataSource.prototype   * @type {Boolean}   */  show: {    get: function () {      return this._entityCollection.show;    },    set: function (value) {      this._entityCollection.show = value;    },  },  /**   * Gets or sets the clustering options for this data source. This object can be shared between multiple data sources.   *   * @memberof GeoJsonDataSource.prototype   * @type {EntityCluster}   */  clustering: {    get: function () {      return this._entityCluster;    },    set: function (value) {      //>>includeStart('debug', pragmas.debug);      if (!defined(value)) {        throw new DeveloperError("value must be defined.");      }      //>>includeEnd('debug');      this._entityCluster = value;    },  },  /**   * Gets the credit that will be displayed for the data source   * @memberof GeoJsonDataSource.prototype   * @type {Credit}   */  credit: {    get: function () {      return this._credit;    },  },});/** * Asynchronously loads the provided GeoJSON or TopoJSON data, replacing any existing data. * * @param {Resource|String|Object} data A url, GeoJSON object, or TopoJSON object to be loaded. * @param {GeoJsonDataSource.LoadOptions} [options] An object specifying configuration options * * @returns {Promise.<GeoJsonDataSource>} a promise that will resolve when the GeoJSON is loaded. */GeoJsonDataSource.prototype.load = function (data, options) {  return preload(this, data, options, true);};/** * Asynchronously loads the provided GeoJSON or TopoJSON data, without replacing any existing data. * * @param {Resource|String|Object} data A url, GeoJSON object, or TopoJSON object to be loaded. * @param {GeoJsonDataSource.LoadOptions} [options] An object specifying configuration options * * @returns {Promise.<GeoJsonDataSource>} a promise that will resolve when the GeoJSON is loaded. */GeoJsonDataSource.prototype.process = function (data, options) {  return preload(this, data, options, false);};function preload(that, data, options, clear) {  //>>includeStart('debug', pragmas.debug);  if (!defined(data)) {    throw new DeveloperError("data is required.");  }  //>>includeEnd('debug');  DataSource.setLoading(that, true);  options = defaultValue(options, defaultValue.EMPTY_OBJECT);  // User specified credit  let credit = options.credit;  if (typeof credit === "string") {    credit = new Credit(credit);  }  that._credit = credit;  let promise = data;  let sourceUri = options.sourceUri;  if (typeof data === "string" || data instanceof Resource) {    data = Resource.createIfNeeded(data);    promise = data.fetchJson();    sourceUri = defaultValue(sourceUri, data.getUrlComponent());    // Add resource credits to our list of credits to display    const resourceCredits = that._resourceCredits;    const credits = data.credits;    if (defined(credits)) {      const length = credits.length;      for (let i = 0; i < length; i++) {        resourceCredits.push(credits[i]);      }    }  }  options = {    describe: defaultValue(options.describe, defaultDescribeProperty),    markerSize: defaultValue(options.markerSize, defaultMarkerSize),    markerSymbol: defaultValue(options.markerSymbol, defaultMarkerSymbol),    markerColor: defaultValue(options.markerColor, defaultMarkerColor),    strokeWidthProperty: new ConstantProperty(      defaultValue(options.strokeWidth, defaultStrokeWidth)    ),    strokeMaterialProperty: new ColorMaterialProperty(      defaultValue(options.stroke, defaultStroke)    ),    fillMaterialProperty: new ColorMaterialProperty(      defaultValue(options.fill, defaultFill)    ),    clampToGround: defaultValue(options.clampToGround, defaultClampToGround),  };  return Promise.resolve(promise)    .then(function (geoJson) {      return load(that, geoJson, options, sourceUri, clear);    })    .catch(function (error) {      DataSource.setLoading(that, false);      that._error.raiseEvent(that, error);      throw error;    });}/** * Updates the data source to the provided time.  This function is optional and * is not required to be implemented.  It is provided for data sources which * retrieve data based on the current animation time or scene state. * If implemented, update will be called by {@link DataSourceDisplay} once a frame. * * @param {JulianDate} time The simulation time. * @returns {Boolean} True if this data source is ready to be displayed at the provided time, false otherwise. */GeoJsonDataSource.prototype.update = function (time) {  return true;};function load(that, geoJson, options, sourceUri, clear) {  let name;  if (defined(sourceUri)) {    name = getFilenameFromUri(sourceUri);  }  if (defined(name) && that._name !== name) {    that._name = name;    that._changed.raiseEvent(that);  }  const typeHandler = geoJsonObjectTypes[geoJson.type];  if (!defined(typeHandler)) {    throw new RuntimeError(`Unsupported GeoJSON object type: ${geoJson.type}`);  }  //Check for a Coordinate Reference System.  const crs = geoJson.crs;  let crsFunction = crs !== null ? defaultCrsFunction : null;  if (defined(crs)) {    if (!defined(crs.properties)) {      throw new RuntimeError("crs.properties is undefined.");    }    const properties = crs.properties;    if (crs.type === "name") {      crsFunction = crsNames[properties.name];      if (!defined(crsFunction)) {        throw new RuntimeError(`Unknown crs name: ${properties.name}`);      }    } else if (crs.type === "link") {      let handler = crsLinkHrefs[properties.href];      if (!defined(handler)) {        handler = crsLinkTypes[properties.type];      }      if (!defined(handler)) {        throw new RuntimeError(          `Unable to resolve crs link: ${JSON.stringify(properties)}`        );      }      crsFunction = handler(properties);    } else if (crs.type === "EPSG") {      crsFunction = crsNames[`EPSG:${properties.code}`];      if (!defined(crsFunction)) {        throw new RuntimeError(`Unknown crs EPSG code: ${properties.code}`);      }    } else {      throw new RuntimeError(`Unknown crs type: ${crs.type}`);    }  }  return Promise.resolve(crsFunction).then(function (crsFunction) {    if (clear) {      that._entityCollection.removeAll();    }    // null is a valid value for the crs, but means the entire load process becomes a no-op    // because we can't assume anything about the coordinates.    if (crsFunction !== null) {      typeHandler(that, geoJson, geoJson, crsFunction, options);    }    return Promise.all(that._promises).then(function () {      that._promises.length = 0;      DataSource.setLoading(that, false);      return that;    });  });}/** * This callback is displayed as part of the GeoJsonDataSource class. * @callback GeoJsonDataSource.describe * @param {Object} properties The properties of the feature. * @param {String} nameProperty The property key that Cesium estimates to have the name of the feature. */export default GeoJsonDataSource;
 |