Skip to content

Commit

Permalink
Include NaturalEarthII as default Cesium layer
Browse files Browse the repository at this point in the history
- Also allow configuration of the Natural Earth base layer just by setting the 'type' to 'NaturalEarthII' for a MapAsset configuration
- Fix issue where imagery layers were stacked on map in reverse order
- Add initial support for TileMapServiceImageryProvider layer type

Relates to #1938 and #1789
  • Loading branch information
robyngit committed Jan 7, 2022
1 parent b388965 commit 86fd21c
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/js/collections/maps/MapAssets.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ define(
model: CesiumVectorData
},
{
types: ['BingMapsImageryProvider', 'IonImageryProvider'],
types: ['BingMapsImageryProvider', 'IonImageryProvider', 'TileMapServiceImageryProvider', 'NaturalEarthII'],
model: CesiumImagery
},
{
Expand Down
5 changes: 4 additions & 1 deletion src/js/models/maps/Map.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,10 @@ define(
pitch: -90,
roll: 0
},
layers: new MapAssets(),
layers: new MapAssets([{
type: 'NaturalEarthII',
label: 'Base layer'
}]),
terrains: new MapAssets(),
selectedFeatures: new Features(),
showToolbar: true,
Expand Down
52 changes: 50 additions & 2 deletions src/js/models/maps/assets/CesiumImagery.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ define(
* @name CesiumImagery#defaults
* @extends MapAsset#defaults
* @type {Object}
* @property {'BingMapsImageryProvider'|'IonImageryProvider'} type A string
* @property {'BingMapsImageryProvider'|'IonImageryProvider'|'TileMapServiceImageryProvider'} type A string
* indicating a Cesium Imagery Provider type. See
* {@link https://cesium.com/learn/cesiumjs-learn/cesiumjs-imagery/#more-imagery-providers}
* @property {Cesium.ImageryLayer} cesiumModel A model created and used by Cesium
Expand Down Expand Up @@ -91,6 +91,20 @@ define(
try {
MapAsset.prototype.initialize.call(this, assetConfig);

if (assetConfig.type == 'NaturalEarthII') {
if (
!assetConfig.cesiumOptions || typeof assetConfig.cesiumOptions !== 'object'
) {
assetConfig.cesiumOptions = {};
}

assetConfig.cesiumOptions.url = Cesium.buildModuleUrl(
'Assets/Textures/NaturalEarthII'
);
this.set('type', 'TileMapServiceImageryProvider')
this.set('cesiumOptions', assetConfig.cesiumOptions);
}

this.createCesiumModel();

this.getThumbnail();
Expand Down Expand Up @@ -243,7 +257,16 @@ define(
var level = provider.minimumLevel

provider.requestImage(x, y, level).then(function (response) {
var objectURL = URL.createObjectURL(response.blob);

let data = response.blob
let objectURL = null

if (!data && response instanceof ImageBitmap) {
objectURL = model.getDataUriFromBitmap(response)
} else {
objectURL = URL.createObjectURL(data);
}

model.set('thumbnail', objectURL)
}).otherwise(function (e) {
console.log('Error requesting an image tile to use as a thumbnail for an ' +
Expand All @@ -258,6 +281,31 @@ define(
}
},

/**
* Gets a data URI from a bitmap image.
* @param {ImageBitmap} bitmap The bitmap image to convert to a data URI
* @returns {String} Returns a string containing the requested data URI.
*/
getDataUriFromBitmap: function (imageBitmap) {
try {
const canvas = document.createElement('canvas');
canvas.width = imageBitmap.width;
canvas.height = imageBitmap.height;
const ctx = canvas.getContext('2d')
// y-flip the image - Natural Earth II bitmaps appear upside down otherwise
// TODO: Test with other imagery layers
ctx.translate(0, imageBitmap.height);
ctx.scale(1, -1);
ctx.drawImage(imageBitmap, 0, 0);
return canvas.toDataURL();
} catch (error) {
console.log(
'There was an error converting an ImageBitmap to a data URL' +
'. Error details: ' + error
);
}
},

// /**
// * Parses the given input into a JSON object to be set on the model.
// *
Expand Down
17 changes: 12 additions & 5 deletions src/js/models/maps/assets/MapAsset.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ define(
* Default attributes for MapAsset models
* @name MapAsset#defaults
* @type {Object}
* @property {('Cesium3DTileset'|'BingMapsImageryProvider'|'IonImageryProvider'|'CesiumTerrainProvider')} type
* @property {('Cesium3DTileset'|'BingMapsImageryProvider'|'IonImageryProvider'|'TileMapServiceImageryProvider'|'CesiumTerrainProvider')} type
* The format of the data. Must be one of the supported types.
* @property {string} label A user friendly name for this asset, to be displayed
* in a map.
Expand Down Expand Up @@ -118,9 +118,12 @@ define(
* description.
* @typedef {Object} MapAssetConfig
* @name MapConfig#MapAssetConfig
* @property {('Cesium3DTileset'|'BingMapsImageryProvider'|'IonImageryProvider'|'CesiumTerrainProvider'|'GeoJsonDataSource')} type -
* @property {('Cesium3DTileset'|'BingMapsImageryProvider'|'IonImageryProvider'|'TileMapServiceImageryProvider'|'NaturalEarthII'|'CesiumTerrainProvider'|'GeoJsonDataSource')} type -
* A string indicating the format of the data. Some of these types correspond
* directly to Cesium classes.
* directly to Cesium classes. The NaturalEarthII type is a special imagery layer
* that automatically sets the cesiumOptions to load the Natural Earth II imagery
* that is shipped with Cesium/MetacatUI. If this type is set, then no other
* cesiumOptions are required.
* @property {(Cesium3DTileset#cesiumOptions|CesiumImagery#cesiumOptions|CesiumTerrain#cesiumOptions|CesiumVectorData#cesiumOptions)} [cesiumOptions] -
* For MapAssets that are configured for Cesium, like
* Cesium3DTilesets, an object with options to pass to the Cesium constructor
Expand Down Expand Up @@ -285,8 +288,12 @@ define(

const model = this;

if (!assetConfig || typeof assetConfig !== 'object') {
assetConfig = {}
}

// Set the color palette
if (assetConfig && assetConfig.colorPalette) {
if (assetConfig.colorPalette) {
this.set('colorPalette', new AssetColorPalette(assetConfig.colorPalette))
}

Expand All @@ -304,7 +311,7 @@ define(
})

// Fetch the icon, if there is one
if (assetConfig && assetConfig.icon) {
if (assetConfig.icon) {
if (model.isSVG(assetConfig.icon)) {
model.updateIcon(assetConfig.icon)
} else {
Expand Down
10 changes: 6 additions & 4 deletions src/js/views/maps/CesiumWidgetView.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ define(
renderFunction: 'addVectorData'
},
{
types: ['BingMapsImageryProvider', 'IonImageryProvider'],
types: ['BingMapsImageryProvider', 'IonImageryProvider','TileMapServiceImageryProvider'],
renderFunction: 'addImagery'
},
{
Expand Down Expand Up @@ -250,10 +250,12 @@ define(
view.listenTo(view.model, 'flyHome', view.flyHome)

// Add each layer from the Map model to the Cesium widget. Render using the
// function configured in the View's mapAssetRenderFunctions property.
view.model.get('layers').forEach(function (mapAsset) {
// function configured in the View's mapAssetRenderFunctions property. Add in
// reverse order for layers to appear in the correct order on the map.
const layers = view.model.get('layers')
_.each(layers.last(layers.length).reverse(), function (mapAsset) {
view.addAsset(mapAsset)
})
});

// The Cesium Widget will support just one terrain option to start. Later,
// we'll allow users to switch between terrains if there is more than one.
Expand Down

0 comments on commit 86fd21c

Please sign in to comment.