123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926 |
- 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 defineProperties from '../Core/defineProperties.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 when from '../ThirdParty/when.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]);
- }
- var crsNames = {
- 'urn:ogc:def:crs:OGC:1.3:CRS84' : defaultCrsFunction,
- 'EPSG:4326' : defaultCrsFunction,
- 'urn:ogc:def:crs:EPSG::4326' : defaultCrsFunction
- };
- var crsLinkHrefs = {};
- var crsLinkTypes = {};
- var defaultMarkerSize = 48;
- var defaultMarkerSymbol;
- var defaultMarkerColor = Color.ROYALBLUE;
- var defaultStroke = Color.YELLOW;
- var defaultStrokeWidth = 2;
- var defaultFill = Color.fromBytes(255, 255, 0, 100);
- var defaultClampToGround = false;
- var sizes = {
- small : 24,
- medium : 48,
- large : 64
- };
- var simpleStyleIdentifiers = ['title', 'description', //
- 'marker-size', 'marker-symbol', 'marker-color', 'stroke', //
- 'stroke-opacity', 'stroke-width', 'fill', 'fill-opacity'];
- function defaultDescribe(properties, nameProperty) {
- var html = '';
- for ( var key in properties) {
- if (properties.hasOwnProperty(key)) {
- if (key === nameProperty || simpleStyleIdentifiers.indexOf(key) !== -1) {
- continue;
- }
- var 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) {
- var 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) {
- var id = geoJson.id;
- if (!defined(id) || geoJson.type !== 'Feature') {
- id = createGuid();
- } else {
- var i = 2;
- var finalId = id;
- while (defined(entityCollection.getById(finalId))) {
- finalId = id + '_' + i;
- i++;
- }
- id = finalId;
- }
- var entity = entityCollection.getOrCreateEntity(id);
- var properties = geoJson.properties;
- if (defined(properties)) {
- entity.properties = properties;
- var nameProperty;
- //Check for the simplestyle specified name first.
- var 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',
- var namePropertyPrecedence = Number.MAX_VALUE;
- for ( var key in properties) {
- if (properties.hasOwnProperty(key) && properties[key]) {
- var 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];
- }
- }
- var description = properties.description;
- if (description !== null) {
- entity.description = !defined(description) ? describe(properties, nameProperty) : new ConstantProperty(description);
- }
- }
- return entity;
- }
- function coordinatesArrayToCartesianArray(coordinates, crsFunction) {
- var positions = new Array(coordinates.length);
- for (var i = 0; i < coordinates.length; i++) {
- positions[i] = crsFunction(coordinates[i]);
- }
- return positions;
- }
- var geoJsonObjectTypes = {
- Feature : processFeature,
- FeatureCollection : processFeatureCollection,
- GeometryCollection : processGeometryCollection,
- LineString : processLineString,
- MultiLineString : processMultiLineString,
- MultiPoint : processMultiPoint,
- MultiPolygon : processMultiPolygon,
- Point : processPoint,
- Polygon : processPolygon,
- Topology : processTopology
- };
- var geometryTypes = {
- GeometryCollection : processGeometryCollection,
- LineString : processLineString,
- MultiLineString : processMultiLineString,
- MultiPoint : processMultiPoint,
- MultiPolygon : processMultiPolygon,
- Point : processPoint,
- Polygon : processPolygon,
- Topology : processTopology
- };
- // GeoJSON processing functions
- function 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.');
- }
- var geometryType = feature.geometry.type;
- var 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) {
- var features = featureCollection.features;
- for (var i = 0, len = features.length; i < len; i++) {
- processFeature(dataSource, features[i], undefined, crsFunction, options);
- }
- }
- function processGeometryCollection(dataSource, geoJson, geometryCollection, crsFunction, options) {
- var geometries = geometryCollection.geometries;
- for (var i = 0, len = geometries.length; i < len; i++) {
- var geometry = geometries[i];
- var geometryType = geometry.type;
- var 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) {
- var symbol = options.markerSymbol;
- var color = options.markerColor;
- var size = options.markerSize;
- var properties = geoJson.properties;
- if (defined(properties)) {
- var cssColor = properties['marker-color'];
- if (defined(cssColor)) {
- color = Color.fromCssColorString(cssColor);
- }
- size = defaultValue(sizes[properties['marker-size']], size);
- var markerSymbol = properties['marker-symbol'];
- if (defined(markerSymbol)) {
- symbol = markerSymbol;
- }
- }
- var 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);
- }
- var 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;
- }
- var entity = createObject(geoJson, dataSource._entityCollection, options.describe);
- entity.billboard = billboard;
- entity.position = new ConstantPositionProperty(crsFunction(coordinates));
- var promise = when(canvasOrPromise).then(function(image) {
- billboard.image = new ConstantProperty(image);
- }).otherwise(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) {
- var coordinates = geometry.coordinates;
- for (var i = 0; i < coordinates.length; i++) {
- createPoint(dataSource, geoJson, crsFunction, coordinates[i], options);
- }
- }
- function createLineString(dataSource, geoJson, crsFunction, coordinates, options) {
- var material = options.strokeMaterialProperty;
- var widthProperty = options.strokeWidthProperty;
- var properties = geoJson.properties;
- if (defined(properties)) {
- var width = properties['stroke-width'];
- if (defined(width)) {
- widthProperty = new ConstantProperty(width);
- }
- var color;
- var stroke = properties.stroke;
- if (defined(stroke)) {
- color = Color.fromCssColorString(stroke);
- }
- var opacity = properties['stroke-opacity'];
- if (defined(opacity) && opacity !== 1.0) {
- if (!defined(color)) {
- color = material.color.clone();
- }
- color.alpha = opacity;
- }
- if (defined(color)) {
- material = new ColorMaterialProperty(color);
- }
- }
- var entity = createObject(geoJson, dataSource._entityCollection, options.describe);
- var 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) {
- var lineStrings = geometry.coordinates;
- for (var 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;
- }
- var outlineColorProperty = options.strokeMaterialProperty.color;
- var material = options.fillMaterialProperty;
- var widthProperty = options.strokeWidthProperty;
- var properties = geoJson.properties;
- if (defined(properties)) {
- var width = properties['stroke-width'];
- if (defined(width)) {
- widthProperty = new ConstantProperty(width);
- }
- var color;
- var stroke = properties.stroke;
- if (defined(stroke)) {
- color = Color.fromCssColorString(stroke);
- }
- var opacity = properties['stroke-opacity'];
- if (defined(opacity) && opacity !== 1.0) {
- if (!defined(color)) {
- color = options.strokeMaterialProperty.color.clone();
- }
- color.alpha = opacity;
- }
- if (defined(color)) {
- outlineColorProperty = new ConstantProperty(color);
- }
- var fillColor;
- var fill = properties.fill;
- if (defined(fill)) {
- fillColor = Color.fromCssColorString(fill);
- fillColor.alpha = material.color.alpha;
- }
- opacity = properties['fill-opacity'];
- if (defined(opacity) && opacity !== material.color.alpha) {
- if (!defined(fillColor)) {
- fillColor = material.color.clone();
- }
- fillColor.alpha = opacity;
- }
- if (defined(fillColor)) {
- material = new ColorMaterialProperty(fillColor);
- }
- }
- var polygon = new PolygonGraphics();
- polygon.outline = new ConstantProperty(true);
- polygon.outlineColor = outlineColorProperty;
- polygon.outlineWidth = widthProperty;
- polygon.material = material;
- polygon.arcType = ArcType.RHUMB;
- var holes = [];
- for (var i = 1, len = coordinates.length; i < len; i++) {
- holes.push(new PolygonHierarchy(coordinatesArrayToCartesianArray(coordinates[i], crsFunction)));
- }
- var 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;
- }
- var 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) {
- var polygons = geometry.coordinates;
- for (var i = 0; i < polygons.length; i++) {
- createPolygon(dataSource, geoJson, crsFunction, polygons[i], options);
- }
- }
- function processTopology(dataSource, geoJson, geometry, crsFunction, options) {
- for ( var property in geometry.objects) {
- if (geometry.objects.hasOwnProperty(property)) {
- var feature = topojson.feature(geometry, geometry.objects[property]);
- var typeHandler = geoJsonObjectTypes[feature.type];
- typeHandler(dataSource, feature, feature, crsFunction, options);
- }
- }
- }
- /**
- * 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
- * var 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 {Object} [options] An object with the following properties:
- * @param {String} [options.sourceUri] Overrides the url to use for resolving relative links.
- * @param {Number} [options.markerSize=GeoJsonDataSource.markerSize] The default size of the map pin created for each point, in pixels.
- * @param {String} [options.markerSymbol=GeoJsonDataSource.markerSymbol] The default symbol of the map pin created for each point.
- * @param {Color} [options.markerColor=GeoJsonDataSource.markerColor] The default color of the map pin created for each point.
- * @param {Color} [options.stroke=GeoJsonDataSource.stroke] The default color of polylines and polygon outlines.
- * @param {Number} [options.strokeWidth=GeoJsonDataSource.strokeWidth] The default width of polylines and polygon outlines.
- * @param {Color} [options.fill=GeoJsonDataSource.fill] The default color for polygon interiors.
- * @param {Boolean} [options.clampToGround=GeoJsonDataSource.clampToGround] true if we want the geometry features (polygons or linestrings) clamped to the ground.
- * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas.
- *
- * @returns {Promise.<GeoJsonDataSource>} A promise that will resolve when the data is loaded.
- */
- GeoJsonDataSource.load = function(data, options) {
- return new GeoJsonDataSource().load(data, options);
- };
- 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;
- }
- }
- });
- 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 {Object} [options] An object with the following properties:
- * @param {String} [options.sourceUri] Overrides the url to use for resolving relative links.
- * @param {GeoJsonDataSource~describe} [options.describe=GeoJsonDataSource.defaultDescribeProperty] A function which returns a Property object (or just a string),
- * which converts the properties into an html description.
- * @param {Number} [options.markerSize=GeoJsonDataSource.markerSize] The default size of the map pin created for each point, in pixels.
- * @param {String} [options.markerSymbol=GeoJsonDataSource.markerSymbol] The default symbol of the map pin created for each point.
- * @param {Color} [options.markerColor=GeoJsonDataSource.markerColor] The default color of the map pin created for each point.
- * @param {Color} [options.stroke=GeoJsonDataSource.stroke] The default color of polylines and polygon outlines.
- * @param {Number} [options.strokeWidth=GeoJsonDataSource.strokeWidth] The default width of polylines and polygon outlines.
- * @param {Color} [options.fill=GeoJsonDataSource.fill] The default color for polygon interiors.
- * @param {Boolean} [options.clampToGround=GeoJsonDataSource.clampToGround] true if we want the features clamped to the ground.
- * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas.
- *
- * @returns {Promise.<GeoJsonDataSource>} a promise that will resolve when the GeoJSON is loaded.
- */
- GeoJsonDataSource.prototype.load = function(data, options) {
- //>>includeStart('debug', pragmas.debug);
- if (!defined(data)) {
- throw new DeveloperError('data is required.');
- }
- //>>includeEnd('debug');
- DataSource.setLoading(this, true);
- options = defaultValue(options, defaultValue.EMPTY_OBJECT);
- // User specified credit
- var credit = options.credit;
- if (typeof credit === 'string') {
- credit = new Credit(credit);
- }
- this._credit = credit;
- var promise = data;
- var 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
- var resourceCredits = this._resourceCredits;
- var credits = data.credits;
- if (defined(credits)) {
- var length = credits.length;
- for (var 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)
- };
- var that = this;
- return when(promise, function(geoJson) {
- return load(that, geoJson, options, sourceUri);
- }).otherwise(function(error) {
- DataSource.setLoading(that, false);
- that._error.raiseEvent(that, error);
- console.log(error);
- return when.reject(error);
- });
- };
- function load(that, geoJson, options, sourceUri) {
- var name;
- if (defined(sourceUri)) {
- name = getFilenameFromUri(sourceUri);
- }
- if (defined(name) && that._name !== name) {
- that._name = name;
- that._changed.raiseEvent(that);
- }
- var typeHandler = geoJsonObjectTypes[geoJson.type];
- if (!defined(typeHandler)) {
- throw new RuntimeError('Unsupported GeoJSON object type: ' + geoJson.type);
- }
- //Check for a Coordinate Reference System.
- var crs = geoJson.crs;
- var crsFunction = crs !== null ? defaultCrsFunction : null;
- if (defined(crs)) {
- if (!defined(crs.properties)) {
- throw new RuntimeError('crs.properties is undefined.');
- }
- var 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') {
- var 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 when(crsFunction, function(crsFunction) {
- 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 when.all(that._promises, 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;
|