Skip to content

Commit

Permalink
Merge pull request #8448 from DanielLeone/fix-tile-map-service-ready-…
Browse files Browse the repository at this point in the history
…promise-rejection

TileMapServiceImageryProvider defaults can cause the browser to hang.
  • Loading branch information
kring authored Mar 11, 2020
2 parents 6cf1259 + 07a7802 commit d48ac3e
Show file tree
Hide file tree
Showing 4 changed files with 294 additions and 240 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Change Log
##### Fixes :wrench:

* Interacting with the Cesium canvas will now blur the previously focused element. This prevents unintended modification of input elements when interacting with the globe.
* `TileMapServiceImageryProvider` will now force `minimumLevel` to 0 if the `tilemapresource.xml` metadata request fails and the `rectangle` is too large for the given detail level [#8448](https://github.com/AnalyticalGraphicsInc/cesium/pull/8448)

### 1.67.0 - 2020-03-02

Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu
* [Jan Wąsak](https://github.com/jhnwsk)
* [Julian Fell](https://github.com/jtfell)
* [Richard Becker](https://github.com/richard3d)
* [Daniel Leone](https://github.com/danielleone)
64 changes: 41 additions & 23 deletions Source/Scene/TileMapServiceImageryProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,38 @@ import UrlTemplateImageryProvider from './UrlTemplateImageryProvider.js';
this._xmlResource.fetchXML().then(this._metadataSuccess).otherwise(this._metadataFailure);
};

/**
* Mutates the properties of a given rectangle so it does not extend outside of the given tiling scheme's rectangle
*/
function confineRectangleToTilingScheme(rectangle, tilingScheme) {
if (rectangle.west < tilingScheme.rectangle.west) {
rectangle.west = tilingScheme.rectangle.west;
}
if (rectangle.east > tilingScheme.rectangle.east) {
rectangle.east = tilingScheme.rectangle.east;
}
if (rectangle.south < tilingScheme.rectangle.south) {
rectangle.south = tilingScheme.rectangle.south;
}
if (rectangle.north > tilingScheme.rectangle.north) {
rectangle.north = tilingScheme.rectangle.north;
}
return rectangle;
}

function calculateSafeMinimumDetailLevel(tilingScheme, rectangle, minimumLevel) {
// Check the number of tiles at the minimum level. If it's more than four,
// try requesting the lower levels anyway, because starting at the higher minimum
// level will cause too many tiles to be downloaded and rendered.
var swTile = tilingScheme.positionToTileXY(Rectangle.southwest(rectangle), minimumLevel);
var neTile = tilingScheme.positionToTileXY(Rectangle.northeast(rectangle), minimumLevel);
var tileCount = (Math.abs(neTile.x - swTile.x) + 1) * (Math.abs(neTile.y - swTile.y) + 1);
if (tileCount > 4) {
return 0;
}
return minimumLevel;
}

TileMapServiceImageryProvider.prototype._metadataSuccess = function(xml) {
var tileFormatRegex = /tileformat/i;
var tileSetRegex = /tileset/i;
Expand Down Expand Up @@ -221,28 +253,9 @@ import UrlTemplateImageryProvider from './UrlTemplateImageryProvider.js';
}

// The rectangle must not be outside the bounds allowed by the tiling scheme.
if (rectangle.west < tilingScheme.rectangle.west) {
rectangle.west = tilingScheme.rectangle.west;
}
if (rectangle.east > tilingScheme.rectangle.east) {
rectangle.east = tilingScheme.rectangle.east;
}
if (rectangle.south < tilingScheme.rectangle.south) {
rectangle.south = tilingScheme.rectangle.south;
}
if (rectangle.north > tilingScheme.rectangle.north) {
rectangle.north = tilingScheme.rectangle.north;
}

// Check the number of tiles at the minimum level. If it's more than four,
// try requesting the lower levels anyway, because starting at the higher minimum
// level will cause too many tiles to be downloaded and rendered.
var swTile = tilingScheme.positionToTileXY(Rectangle.southwest(rectangle), minimumLevel);
var neTile = tilingScheme.positionToTileXY(Rectangle.northeast(rectangle), minimumLevel);
var tileCount = (Math.abs(neTile.x - swTile.x) + 1) * (Math.abs(neTile.y - swTile.y) + 1);
if (tileCount > 4) {
minimumLevel = 0;
}
rectangle = confineRectangleToTilingScheme(rectangle, tilingScheme);
// clamp our minimum detail level to something that isn't going to request a ridiculous number of tiles
minimumLevel = calculateSafeMinimumDetailLevel(tilingScheme, rectangle, minimumLevel);

var templateResource = this._tmsResource.getDerivedResource({
url : '{z}/{x}/{reverseY}.' + fileExtension
Expand All @@ -267,10 +280,15 @@ import UrlTemplateImageryProvider from './UrlTemplateImageryProvider.js';
var fileExtension = defaultValue(options.fileExtension, 'png');
var tileWidth = defaultValue(options.tileWidth, 256);
var tileHeight = defaultValue(options.tileHeight, 256);
var minimumLevel = defaultValue(options.minimumLevel, 0);
var maximumLevel = options.maximumLevel;
var tilingScheme = defined(options.tilingScheme) ? options.tilingScheme : new WebMercatorTilingScheme({ellipsoid : options.ellipsoid});

var rectangle = defaultValue(options.rectangle, tilingScheme.rectangle);
// The rectangle must not be outside the bounds allowed by the tiling scheme.
rectangle = confineRectangleToTilingScheme(rectangle, tilingScheme);

// make sure we use a safe minimum detail level, so we don't request a ridiculous number of tiles
var minimumLevel = calculateSafeMinimumDetailLevel(tilingScheme, rectangle, options.maximumLevel);

var templateResource = this._tmsResource.getDerivedResource({
url : '{z}/{x}/{reverseY}.' + fileExtension
Expand Down
Loading

0 comments on commit d48ac3e

Please sign in to comment.