-
Notifications
You must be signed in to change notification settings - Fork 8.6k
[Maps] Handle unavailable tilemap services #28852
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
Changes from all commits
e482029
6b911c3
abafa1c
ad4184b
58651ae
bfc1db4
4a6f50e
3b2bba5
43a021f
ab80f12
b4c16ce
76b357c
eca78ef
7b75249
0c3dd1f
2497b9c
adf4962
0a205a3
11fcf24
14e94cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,7 +17,6 @@ export class AbstractLayer { | |
| this._descriptor = AbstractLayer.createDescriptor(layerDescriptor); | ||
| this._source = source; | ||
| this._style = style; | ||
|
|
||
| if (this._descriptor.dataRequests) { | ||
| this._dataRequests = this._descriptor.dataRequests.map(dataRequest => new DataRequest(dataRequest)); | ||
| } else { | ||
|
|
@@ -64,7 +63,10 @@ export class AbstractLayer { | |
| } | ||
|
|
||
| async getAttributions() { | ||
| return await this._source.getAttributions(); | ||
| if (!this.hasErrors()) { | ||
| return await this._source.getAttributions(); | ||
| } | ||
| return []; | ||
| } | ||
|
|
||
| getLabel() { | ||
|
|
@@ -139,21 +141,20 @@ export class AbstractLayer { | |
| return this._source.renderSourceSettingsEditor({ onChange }); | ||
| }; | ||
|
|
||
| getSourceDataRequest() { | ||
| return this._dataRequests.find(dataRequest => dataRequest.getDataId() === 'source'); | ||
| } | ||
|
|
||
| isLayerLoading() { | ||
| return this._dataRequests.some(dataRequest => dataRequest.isLoading()); | ||
| } | ||
|
|
||
| dataHasLoadError() { | ||
| return this._dataRequests.some(dataRequest => dataRequest.hasLoadError()); | ||
| hasErrors() { | ||
| return _.get(this._descriptor, 'isInErrorState', false); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not needed, just preferred |
||
| } | ||
|
|
||
| getDataLoadError() { | ||
| const loadErrors = this._dataRequests | ||
| .filter(dataRequest => dataRequest.hasLoadError()) | ||
| .map(dataRequest => { | ||
| return dataRequest._descriptor.dataLoadError; | ||
| }); | ||
| return loadErrors.join(','); | ||
| getErrors() { | ||
| return this.hasErrors() ? this._descriptor.errorMessage : ''; | ||
| } | ||
|
|
||
| toLayerDescriptor() { | ||
|
|
@@ -219,10 +220,6 @@ export class AbstractLayer { | |
| return style.renderEditor(options); | ||
| } | ||
|
|
||
| getSourceDataRequest() { | ||
| return this._dataRequests.find(dataRequest => dataRequest.getDataId() === 'source'); | ||
| } | ||
|
|
||
| getIndexPatternIds() { | ||
| return []; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,8 @@ import React from 'react'; | |
| import { EuiIcon } from '@elastic/eui'; | ||
| import { TileStyle } from '../layers/styles/tile_style'; | ||
|
|
||
| const TMS_LOAD_TIMEOUT = 32000; | ||
|
|
||
| export class TileLayer extends AbstractLayer { | ||
|
|
||
| static type = "TILE"; | ||
|
|
@@ -30,29 +32,65 @@ export class TileLayer extends AbstractLayer { | |
| return tileLayerDescriptor; | ||
| } | ||
|
|
||
| _tileLoadErrorTracker(map, url) { | ||
| let tileLoad; | ||
| map.on('dataloading', ({ tile }) => { | ||
| if (tile && tile.request) { | ||
| // If at least one tile loads, endpoint/resource is valid | ||
| tile.request.onloadend = ({ loaded }) => { | ||
| if (loaded) { | ||
| tileLoad = true; | ||
| } | ||
| }; | ||
| } | ||
| }); | ||
|
|
||
| return new Promise((resolve, reject) => { | ||
| let tileLoadTimer = null; | ||
|
|
||
| syncLayerWithMB(mbMap) { | ||
| const clearChecks = () => { | ||
| clearTimeout(tileLoadTimer); | ||
| map.off('dataloading'); | ||
| }; | ||
|
|
||
| tileLoadTimer = setTimeout(() => { | ||
| if (!tileLoad) { | ||
| reject(new Error(`Tiles from "${url}" could not be loaded`)); | ||
| } else { | ||
| resolve(); | ||
| } | ||
| clearChecks(); | ||
| }, TMS_LOAD_TIMEOUT); | ||
| }); | ||
| } | ||
|
|
||
| async syncLayerWithMB(mbMap) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we make this signature In practice, the completion of this method (https://github.com/thomasneirynck/kibana/blob/93fe5b7b2f566cc4519cc257834b110eb8f8248b/x-pack/plugins/gis/public/components/map/mb/view.js#L194) now no longer guarantees that the map has synced. |
||
| const source = mbMap.getSource(this.getId()); | ||
| const layerId = this.getId() + '_raster'; | ||
| if (!source) { | ||
| const url = this._source.getUrlTemplate(); | ||
| mbMap.addSource(this.getId(), { | ||
| type: 'raster', | ||
| tiles: [url], | ||
| tileSize: 256, | ||
| scheme: 'xyz', | ||
| }); | ||
|
|
||
| mbMap.addLayer({ | ||
| id: layerId, | ||
| type: 'raster', | ||
| source: this.getId(), | ||
| minzoom: 0, | ||
| maxzoom: 22, | ||
| }); | ||
|
|
||
| if (source) { | ||
| return; | ||
| } | ||
|
|
||
| const url = this._source.getUrlTemplate(); | ||
| const sourceId = this.getId(); | ||
| mbMap.addSource(sourceId, { | ||
| type: 'raster', | ||
| tiles: [url], | ||
| tileSize: 256, | ||
| scheme: 'xyz', | ||
| }); | ||
|
|
||
| mbMap.addLayer({ | ||
| id: layerId, | ||
| type: 'raster', | ||
| source: sourceId, | ||
| minzoom: 0, | ||
| maxzoom: 22, | ||
| }); | ||
|
|
||
| await this._tileLoadErrorTracker(mbMap, url); | ||
|
|
||
| mbMap.setLayoutProperty(layerId, 'visibility', this.isVisible() ? 'visible' : 'none'); | ||
| mbMap.setLayerZoomRange(layerId, this._descriptor.minZoom, this._descriptor.maxZoom); | ||
| this._style && this._style.setMBPaintProperties({ | ||
|
|
@@ -73,5 +111,8 @@ export class TileLayer extends AbstractLayer { | |
| /> | ||
| ); | ||
| } | ||
| isLayerLoading() { | ||
| return false; | ||
| } | ||
|
|
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This causes the syncing operation to unhook from the callstack, and completion is not guaranteed.