Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added support for Bing Maps' AerialWithLabelsOnDemand imagery set, as… #41

Merged
merged 5 commits into from
May 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Source/Core/Resource.js
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,8 @@ define([
window.URL.revokeObjectURL(generatedBlobResource.url);
}

error.blob = generatedBlob;

return when.reject(error);
});
};
Expand Down
56 changes: 41 additions & 15 deletions Source/Scene/BingMapsImageryProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ define([
'../ThirdParty/when',
'./BingMapsStyle',
'./DiscardMissingTileImagePolicy',
'./DiscardEmptyTileImagePolicy',
'./ImageryProvider'
], function(
BingMapsApi,
Expand All @@ -39,6 +40,7 @@ define([
when,
BingMapsStyle,
DiscardMissingTileImagePolicy,
DiscardEmptyTilePolicy,
ImageryProvider) {
'use strict';

Expand All @@ -61,15 +63,16 @@ define([
* for information on the supported cultures.
* @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
* @param {TileDiscardPolicy} [options.tileDiscardPolicy] The policy that determines if a tile
* is invalid and should be discarded. If this value is not specified, a default
* {@link DiscardMissingTileImagePolicy} is used which requests
* tile 0,0 at the maximum tile level and checks pixels (0,0), (120,140), (130,160),
* (200,50), and (200,200). If all of these pixels are transparent, the discard check is
* disabled and no tiles are discarded. If any of them have a non-transparent color, any
* tile that has the same values in these pixel locations is discarded. The end result of
* these defaults should be correct tile discarding for a standard Bing Maps server. To ensure
* that no tiles are discarded, construct and pass a {@link NeverTileDiscardPolicy} for this
* parameter.
* is invalid and should be discarded. The default value will depend on the map style. If
* `BingMapsStyle.AERIAL_WITH_LABELS_ON_DEMAND` or `BingMapsStyle.ROADS_ON_DEMAND` is used, then a
* {@link DiscardEmptyTileImagePolicy} will be used to handle the Bing Maps API sending no content instead of
* a missing tile image, a behaviour specific to that imagery set. In all over cases, a default
* {@link DiscardMissingTileImagePolicy} is used which requests tile 0,0 at the maximum tile level and checks
* pixels (0,0), (120,140), (130,160), (200,50), and (200,200). If all of these pixels are transparent, the
* discard check is disabled and no tiles are discarded. If any of them have a non-transparent color, any
* tile that has the same values in these pixel locations is discarded. The end result of these defaults
* should be correct tile discarding for a standard Bing Maps server. To ensure that no tiles are discarded,
* construct and pass a {@link NeverTileDiscardPolicy} for this parameter.
*
* @see ArcGisMapServerImageryProvider
* @see GoogleEarthEnterpriseMapsProvider
Expand Down Expand Up @@ -171,11 +174,18 @@ define([

// Install the default tile discard policy if none has been supplied.
if (!defined(that._tileDiscardPolicy)) {
that._tileDiscardPolicy = new DiscardMissingTileImagePolicy({
missingImageUrl : buildImageResource(that, 0, 0, that._maximumLevel).url,
pixelsToCheck : [new Cartesian2(0, 0), new Cartesian2(120, 140), new Cartesian2(130, 160), new Cartesian2(200, 50), new Cartesian2(200, 200)],
disableCheckIfAllPixelsAreTransparent : true
});
// Our default depends on which map style we're using.
if (that._mapStyle === BingMapsStyle.AERIAL_WITH_LABELS_ON_DEMAND
|| that._mapStyle === BingMapsStyle.ROAD_ON_DEMAND) {
// this map style uses a different API, which returns a tile with no data instead of a placeholder image
that._tileDiscardPolicy = new DiscardEmptyTilePolicy();
} else {
that._tileDiscardPolicy = new DiscardMissingTileImagePolicy({
missingImageUrl : buildImageResource(that, 0, 0, that._maximumLevel).url,
pixelsToCheck : [new Cartesian2(0, 0), new Cartesian2(120, 140), new Cartesian2(130, 160), new Cartesian2(200, 50), new Cartesian2(200, 200)],
disableCheckIfAllPixelsAreTransparent : true
});
}
}

var attributionList = that._attributionList = resource.imageryProviders;
Expand Down Expand Up @@ -533,7 +543,23 @@ define([
}
//>>includeEnd('debug');

return ImageryProvider.loadImage(this, buildImageResource(this, x, y, level, request));
var promise = ImageryProvider.loadImage(this, buildImageResource(this, x, y, level, request));

if (defined(promise)) {
return promise.otherwise(function(error) {

// One possible cause of an error here is that the image we tried to load was empty. This isn't actually
// a problem. In some imagery sets (eg. `BingMapsStyle.AERIAL_WITH_LABELS_ON_DEMAND`), an empty image is
// returned rather than a blank "This Image is Missing" placeholder image. In this case, we supress the
// error.
if (defined(error.blob) && error.blob.size === 0) {
return DiscardEmptyTilePolicy.EMPTY_IMAGE;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're not handling the error, you need to re-throw it. Otherwise it acts like a successful result yielding undefined.

return when.reject(error);
});
}

return undefined;
};

/**
Expand Down
20 changes: 20 additions & 0 deletions Source/Scene/BingMapsStyle.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,37 @@ define([
*
* @type {String}
* @constant
* @deprecated See https://github.com/AnalyticalGraphicsInc/cesium/issues/7128.
* Use `BingMapsStyle.AERIAL_WITH_LABELS_ON_DEMAND` instead
*/
AERIAL_WITH_LABELS : 'AerialWithLabels',

/**
* Aerial imagery with a road overlay.
*
* @type {String}
* @constant
*/
AERIAL_WITH_LABELS_ON_DEMAND : 'AerialWithLabelsOnDemand',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add the other new styles, too: https://docs.microsoft.com/en-us/bingmaps/rest-services/imagery/get-imagery-metadata
It doesn't make sense to add the BirdsEye or Streetside ones, but the others should be added.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a couple still missing (unless there's some reason I'm not aware of that they can't be used):
CanvasDark, CanvasLight, CanvasGray, and OrdnanceSurvey


/**
* Roads without additional imagery.
*
* @type {String}
* @constant
* @deprecated See https://github.com/AnalyticalGraphicsInc/cesium/issues/7128.
* Use `BingMapsStyle.ROAD_ON_DEMAND` instead
*/
ROAD : 'Road',

/**
* Roads without additional imagery.
*
* @type {String}
* @constant
*/
ROAD_ON_DEMAND : 'RoadOnDemand',

/**
* A dark version of the road maps.
*
Expand Down
43 changes: 43 additions & 0 deletions Source/Scene/DiscardEmptyTileImagePolicy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
define([
'../Core/defined',
'../Core/defaultValue'
], function(
defined,
defaultValue) {

/**
* A policy for discarding tile images that contain no data (and so aren't actually images).
*
* @alias DiscardEmptyTileImagePolicy
* @constructor
*
* @see DiscardMissingTileImagePolicy
*/
function DiscardEmptyTileImagePolicy(options) {
}

/**
* Determines if the discard policy is ready to process images.
* @returns {Boolean} True if the discard policy is ready to process images; otherwise, false.
*/
DiscardEmptyTileImagePolicy.prototype.isReady = function() {
return true;
};

/**
* Given a tile image, decide whether to discard that image.
*
* @param {Image} image An image to test.
* @returns {Boolean} True if the image should be discarded; otherwise, false.
*/
DiscardEmptyTileImagePolicy.prototype.shouldDiscardImage = function(image) {
return DiscardEmptyTileImagePolicy.EMPTY_IMAGE === image;
};

/**
* Default value for representing an empty image.
*/
DiscardEmptyTileImagePolicy.EMPTY_IMAGE = {};

return DiscardEmptyTileImagePolicy;
});