mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Maps] Custom raster source example plugin (#136761)
This commit is contained in:
parent
8b0d873e1e
commit
69dc7e2b77
17 changed files with 457 additions and 10 deletions
|
@ -12,6 +12,7 @@ import type {
|
|||
Source,
|
||||
GeoJSONSource,
|
||||
VectorTileSource,
|
||||
RasterTileSource,
|
||||
StyleSpecification,
|
||||
MapEvent,
|
||||
MapOptions,
|
||||
|
@ -48,6 +49,7 @@ export type {
|
|||
Source,
|
||||
GeoJSONSource,
|
||||
VectorTileSource,
|
||||
RasterTileSource,
|
||||
MapEvent,
|
||||
MapOptions,
|
||||
MapMouseEvent,
|
||||
|
|
|
@ -279,6 +279,8 @@
|
|||
"@kbn/testing-embedded-lens-plugin/*": ["x-pack/examples/testing_embedded_lens/*"],
|
||||
"@kbn/third-party-lens-navigation-prompt-plugin": ["x-pack/examples/third_party_lens_navigation_prompt"],
|
||||
"@kbn/third-party-lens-navigation-prompt-plugin/*": ["x-pack/examples/third_party_lens_navigation_prompt/*"],
|
||||
"@kbn/maps-custom-raster-source-plugin": ["x-pack/examples/third_party_maps_source_example"],
|
||||
"@kbn/maps-custom-raster-source-plugin/*": ["x-pack/examples/third_party_maps_source_example/*"],
|
||||
"@kbn/third-party-vis-lens-example-plugin": ["x-pack/examples/third_party_vis_lens_example"],
|
||||
"@kbn/third-party-vis-lens-example-plugin/*": ["x-pack/examples/third_party_vis_lens_example/*"],
|
||||
"@kbn/triggers-actions-ui-example-plugin": ["x-pack/examples/triggers_actions_ui_example"],
|
||||
|
|
17
x-pack/examples/third_party_maps_source_example/README.md
Executable file
17
x-pack/examples/third_party_maps_source_example/README.md
Executable file
|
@ -0,0 +1,17 @@
|
|||
# Third party maps source example plugin
|
||||
|
||||
An example plugin for a custom raster tile source in Maps.
|
||||
|
||||
This example plugin uses a [time-enabled radar imagery service from the U.S. National Weather Service](https://idpgis.ncep.noaa.gov/arcgis/rest/services/radar/radar_base_reflectivity_time/ImageServer). The service URL contains a `{time}` template field that is populated as [Unix time](https://en.wikipedia.org/wiki/Unix_time) from the Kibana time picker. The time slider in Maps can also be used to animate the service.
|
||||
|
||||
## Demo
|
||||
1. Open a new Map and modify the time picker to the "Last 2 hours".
|
||||
2. Click "Add layer" and choose "Weather" to add the layer to the map.
|
||||
3. You should see current precipitation models over the U.S.
|
||||
4. Use the timeslider to animate the radar model.
|
||||
|
||||
---
|
||||
|
||||
## Development
|
||||
|
||||
See the [kibana contributing guide](https://github.com/elastic/kibana/blob/main/CONTRIBUTING.md) for instructions setting up your development environment.
|
9
x-pack/examples/third_party_maps_source_example/common/index.ts
Executable file
9
x-pack/examples/third_party_maps_source_example/common/index.ts
Executable file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export const PLUGIN_ID = 'mapsCustomRasterSource';
|
||||
export const PLUGIN_NAME = 'Third party maps source example';
|
15
x-pack/examples/third_party_maps_source_example/kibana.json
Executable file
15
x-pack/examples/third_party_maps_source_example/kibana.json
Executable file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"id": "mapsCustomRasterSource",
|
||||
"version": "1.0.0",
|
||||
"kibanaVersion": "kibana",
|
||||
"configPath": ["third_party_maps_source_example"],
|
||||
"owner": {
|
||||
"name": "kibana-gis",
|
||||
"githubTeam": "kibana-gis"
|
||||
},
|
||||
"description": "An example plugin for creating a custom raster source for Elastic Maps",
|
||||
"server": false,
|
||||
"ui": true,
|
||||
"requiredPlugins": ["navigation", "data", "maps", "developerExamples", "kibanaReact"],
|
||||
"optionalPlugins": ["kibanaUtils", "kibanaReact"]
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { EuiCallOut, EuiPanel, htmlIdGenerator } from '@elastic/eui';
|
||||
import { RenderWizardArguments } from '@kbn/maps-plugin/public';
|
||||
import { LayerDescriptor, LAYER_TYPE } from '@kbn/maps-plugin/common';
|
||||
import { CustomRasterSource } from './custom_raster_source';
|
||||
|
||||
export class CustomRasterEditor extends Component<RenderWizardArguments> {
|
||||
componentDidMount() {
|
||||
const customRasterLayerDescriptor: LayerDescriptor = {
|
||||
id: htmlIdGenerator()(),
|
||||
type: LAYER_TYPE.RASTER_TILE,
|
||||
sourceDescriptor: CustomRasterSource.createDescriptor(),
|
||||
style: {
|
||||
type: 'RASTER',
|
||||
},
|
||||
alpha: 1,
|
||||
};
|
||||
this.props.previewLayers([customRasterLayerDescriptor]);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<EuiPanel>
|
||||
<EuiCallOut title="NOAA Weather">
|
||||
<p>
|
||||
Displays NOAA weather data. Kibana time is passed to request so weather data is
|
||||
displayed for selected time range.
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</EuiPanel>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { LAYER_WIZARD_CATEGORY } from '@kbn/maps-plugin/common';
|
||||
import type { LayerWizard, RenderWizardArguments } from '@kbn/maps-plugin/public';
|
||||
import { PLUGIN_ID } from '../../common';
|
||||
import { CustomRasterEditor } from './custom_raster_editor';
|
||||
|
||||
export const customRasterLayerWizard: LayerWizard = {
|
||||
id: PLUGIN_ID,
|
||||
categories: [LAYER_WIZARD_CATEGORY.REFERENCE],
|
||||
title: 'Weather',
|
||||
description: 'Weather data provided by NOAA',
|
||||
icon: '',
|
||||
order: 100,
|
||||
renderWizard: (renderWizardArguments: RenderWizardArguments) => {
|
||||
return <CustomRasterEditor {...renderWizardArguments} />;
|
||||
},
|
||||
};
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ReactElement } from 'react';
|
||||
import { calculateBounds } from '@kbn/data-plugin/common';
|
||||
import { FieldFormatter, MIN_ZOOM, MAX_ZOOM } from '@kbn/maps-plugin/common';
|
||||
import type {
|
||||
AbstractSourceDescriptor,
|
||||
Attribution,
|
||||
DataFilters,
|
||||
DataRequestMeta,
|
||||
Timeslice,
|
||||
} from '@kbn/maps-plugin/common/descriptor_types';
|
||||
import type {
|
||||
IField,
|
||||
ImmutableSourceProperty,
|
||||
ITMSSource,
|
||||
SourceEditorArgs,
|
||||
} from '@kbn/maps-plugin/public';
|
||||
|
||||
type CustomRasterSourceDescriptor = AbstractSourceDescriptor;
|
||||
|
||||
export class CustomRasterSource implements ITMSSource {
|
||||
static type = 'CUSTOM_RASTER';
|
||||
|
||||
readonly _descriptor: CustomRasterSourceDescriptor;
|
||||
|
||||
static createDescriptor(): CustomRasterSourceDescriptor {
|
||||
return {
|
||||
type: CustomRasterSource.type,
|
||||
};
|
||||
}
|
||||
|
||||
constructor(sourceDescriptor: CustomRasterSourceDescriptor) {
|
||||
this._descriptor = sourceDescriptor;
|
||||
}
|
||||
|
||||
cloneDescriptor(): CustomRasterSourceDescriptor {
|
||||
return {
|
||||
type: this._descriptor.type,
|
||||
};
|
||||
}
|
||||
|
||||
async supportsFitToBounds(): Promise<boolean> {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* return list of immutable source properties.
|
||||
* Immutable source properties are properties that can not be edited by the user.
|
||||
*/
|
||||
async getImmutableProperties(): Promise<ImmutableSourceProperty[]> {
|
||||
return [];
|
||||
}
|
||||
|
||||
getType(): string {
|
||||
return this._descriptor.type;
|
||||
}
|
||||
|
||||
async getDisplayName(): Promise<string> {
|
||||
return '';
|
||||
}
|
||||
|
||||
getAttributionProvider(): (() => Promise<Attribution[]>) | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
isFieldAware(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
isGeoGridPrecisionAware(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
isQueryAware(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
getFieldNames(): string[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
renderSourceSettingsEditor(sourceEditorArgs: SourceEditorArgs): ReactElement<any> | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
getApplyGlobalQuery(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
getApplyGlobalTime(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
getApplyForceRefresh(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
getIndexPatternIds(): string[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
getQueryableIndexPatternIds(): string[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
getGeoGridPrecision(zoom: number): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
isESSource(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns function used to format value
|
||||
async createFieldFormatter(field: IField): Promise<FieldFormatter | null> {
|
||||
return null;
|
||||
}
|
||||
|
||||
async getValueSuggestions(field: IField, query: string): Promise<string[]> {
|
||||
return [];
|
||||
}
|
||||
|
||||
async isTimeAware(): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
isFilterByMapBounds(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
getMinZoom(): number {
|
||||
return MIN_ZOOM;
|
||||
}
|
||||
|
||||
getMaxZoom(): number {
|
||||
return MAX_ZOOM;
|
||||
}
|
||||
|
||||
async getLicensedFeatures(): Promise<[]> {
|
||||
return [];
|
||||
}
|
||||
|
||||
getUpdateDueToTimeslice(prevMeta: DataRequestMeta, timeslice?: Timeslice): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
async getUrlTemplate(dataFilters: DataFilters): Promise<string> {
|
||||
const defaultUrl =
|
||||
'https://new.nowcoast.noaa.gov/arcgis/rest/services/nowcoast/radar_meteo_imagery_nexrad_time/MapServer/export?dpi=96&transparent=true&format=png32&time={time}&layers=show%3A3&bbox=-{bbox-epsg-3857}&bboxSR=3857&imageSR=3857&size=256%2C256&f=image';
|
||||
|
||||
const { timeslice, timeFilters } = dataFilters;
|
||||
let timestamp;
|
||||
|
||||
if (timeslice) {
|
||||
// Use the value from the timeslider
|
||||
timestamp = new Date(timeslice.to).getTime();
|
||||
} else {
|
||||
const { max } = calculateBounds(timeFilters);
|
||||
timestamp = max ? max.valueOf() : Date.now();
|
||||
}
|
||||
|
||||
// Replace the '{time}' template value in the URL with the Unix timestamp
|
||||
return defaultUrl.replace('{time}', timestamp.toString());
|
||||
}
|
||||
}
|
17
x-pack/examples/third_party_maps_source_example/public/index.ts
Executable file
17
x-pack/examples/third_party_maps_source_example/public/index.ts
Executable file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import './index.scss';
|
||||
|
||||
import { MapsCustomRasterSourcePlugin } from './plugin';
|
||||
|
||||
// This exports static code and TypeScript types,
|
||||
// as well as, Kibana Platform `plugin()` initializer.
|
||||
export function plugin() {
|
||||
return new MapsCustomRasterSourcePlugin();
|
||||
}
|
||||
export type { MapsCustomRasterSourcePluginSetup, MapsCustomRasterSourcePluginStart } from './types';
|
68
x-pack/examples/third_party_maps_source_example/public/plugin.ts
Executable file
68
x-pack/examples/third_party_maps_source_example/public/plugin.ts
Executable file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { CoreSetup, Plugin } from '@kbn/core/public';
|
||||
import { MapsCustomRasterSourcePluginSetup, MapsCustomRasterSourcePluginStart } from './types';
|
||||
import { CustomRasterSource } from './classes/custom_raster_source';
|
||||
import { customRasterLayerWizard } from './classes/custom_raster_layer_wizard';
|
||||
import { PLUGIN_ID, PLUGIN_NAME } from '../common';
|
||||
import image from './third_party_maps_source_example.png';
|
||||
|
||||
export class MapsCustomRasterSourcePlugin
|
||||
implements
|
||||
Plugin<void, void, MapsCustomRasterSourcePluginSetup, MapsCustomRasterSourcePluginStart>
|
||||
{
|
||||
public setup(
|
||||
core: CoreSetup<MapsCustomRasterSourcePluginStart>,
|
||||
{ developerExamples, maps: mapsSetup }: MapsCustomRasterSourcePluginSetup
|
||||
) {
|
||||
// Register the Custom raster layer wizard with the Maps application
|
||||
mapsSetup.registerSource({
|
||||
type: CustomRasterSource.type,
|
||||
ConstructorFunction: CustomRasterSource,
|
||||
});
|
||||
mapsSetup.registerLayerWizard(customRasterLayerWizard);
|
||||
|
||||
// Register an application into the side navigation menu
|
||||
core.application.register({
|
||||
id: PLUGIN_ID,
|
||||
title: PLUGIN_NAME,
|
||||
mount: ({ history }) => {
|
||||
(async () => {
|
||||
const [coreStart] = await core.getStartServices();
|
||||
// if it's a regular navigation, open a new map
|
||||
if (history.action === 'PUSH') {
|
||||
coreStart.application.navigateToApp('maps', { path: 'map' });
|
||||
} else {
|
||||
coreStart.application.navigateToApp('developerExamples');
|
||||
}
|
||||
})();
|
||||
return () => {};
|
||||
},
|
||||
});
|
||||
|
||||
developerExamples.register({
|
||||
appId: PLUGIN_ID,
|
||||
title: PLUGIN_NAME,
|
||||
description: 'Example of using a third-party custom source with Elastic Maps',
|
||||
image,
|
||||
links: [
|
||||
{
|
||||
label: 'README',
|
||||
href: 'https://github.com/elastic/kibana/tree/main/x-pack/examples/third_party_maps_source_example',
|
||||
iconType: 'logoGithub',
|
||||
size: 's',
|
||||
target: '_blank',
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
public start() {}
|
||||
|
||||
public stop() {}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 244 KiB |
17
x-pack/examples/third_party_maps_source_example/public/types.ts
Executable file
17
x-pack/examples/third_party_maps_source_example/public/types.ts
Executable file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { DeveloperExamplesSetup } from '@kbn/developer-examples-plugin/public';
|
||||
import { MapsPluginSetup, MapsPluginStart } from '@kbn/maps-plugin/public/plugin';
|
||||
|
||||
export interface MapsCustomRasterSourcePluginSetup {
|
||||
developerExamples: DeveloperExamplesSetup;
|
||||
maps: MapsPluginSetup;
|
||||
}
|
||||
export interface MapsCustomRasterSourcePluginStart {
|
||||
maps: MapsPluginStart;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./target/types",
|
||||
},
|
||||
"include": [
|
||||
"public/**/*.ts",
|
||||
"public/**/*.tsx",
|
||||
"common/**/*.ts",
|
||||
"../../../typings/**/*",
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../../../src/core/tsconfig.json" },
|
||||
{ "path": "../../plugins/maps/tsconfig.json"},
|
||||
{ "path": "../../../examples/developer_examples/tsconfig.json" },
|
||||
]
|
||||
}
|
|
@ -5,14 +5,19 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { Map as MbMap } from '@kbn/mapbox-gl';
|
||||
import type { Map as MbMap, RasterTileSource } from '@kbn/mapbox-gl';
|
||||
import _ from 'lodash';
|
||||
import { AbstractLayer } from '../layer';
|
||||
import { SOURCE_DATA_REQUEST_ID, LAYER_TYPE, LAYER_STYLE_TYPE } from '../../../../common/constants';
|
||||
import { LayerDescriptor } from '../../../../common/descriptor_types';
|
||||
import { LayerDescriptor, Timeslice } from '../../../../common/descriptor_types';
|
||||
import { TileStyle } from '../../styles/tile/tile_style';
|
||||
import { ITMSSource } from '../../sources/tms_source';
|
||||
import { DataRequestContext } from '../../../actions';
|
||||
import { canSkipSourceUpdate } from '../../util/can_skip_fetch';
|
||||
|
||||
interface RasterTileSourceData {
|
||||
url: string;
|
||||
}
|
||||
|
||||
export class RasterTileLayer extends AbstractLayer {
|
||||
static createDescriptor(options: Partial<LayerDescriptor>) {
|
||||
|
@ -53,16 +58,33 @@ export class RasterTileLayer extends AbstractLayer {
|
|||
}
|
||||
|
||||
async syncData({ startLoading, stopLoading, onLoadError, dataFilters }: DataRequestContext) {
|
||||
const sourceDataRequest = this.getSourceDataRequest();
|
||||
if (sourceDataRequest) {
|
||||
// data is immmutable
|
||||
return;
|
||||
const source = this.getSource();
|
||||
const nextMeta = {
|
||||
...dataFilters,
|
||||
applyGlobalTime: source.getApplyGlobalTime(),
|
||||
};
|
||||
const prevDataRequest = this.getSourceDataRequest();
|
||||
if (prevDataRequest) {
|
||||
const prevMeta = prevDataRequest?.getMeta();
|
||||
const canSkip = await canSkipSourceUpdate({
|
||||
extentAware: false,
|
||||
source,
|
||||
prevDataRequest,
|
||||
nextRequestMeta: nextMeta,
|
||||
getUpdateDueToTimeslice: (timeslice?: Timeslice) => {
|
||||
if (!prevMeta) return true;
|
||||
return source.getUpdateDueToTimeslice(prevMeta, timeslice);
|
||||
},
|
||||
});
|
||||
if (canSkip) return;
|
||||
}
|
||||
const requestToken = Symbol(`layer-source-refresh:${this.getId()} - source`);
|
||||
startLoading(SOURCE_DATA_REQUEST_ID, requestToken, dataFilters);
|
||||
try {
|
||||
const url = await this.getSource().getUrlTemplate();
|
||||
stopLoading(SOURCE_DATA_REQUEST_ID, requestToken, { url }, {});
|
||||
startLoading(SOURCE_DATA_REQUEST_ID, requestToken, nextMeta);
|
||||
const data: RasterTileSourceData = {
|
||||
url: await source.getUrlTemplate(dataFilters),
|
||||
};
|
||||
stopLoading(SOURCE_DATA_REQUEST_ID, requestToken, data, {});
|
||||
} catch (error) {
|
||||
onLoadError(SOURCE_DATA_REQUEST_ID, requestToken, error.message);
|
||||
}
|
||||
|
@ -84,7 +106,26 @@ export class RasterTileLayer extends AbstractLayer {
|
|||
return this.getId() === mbSourceId;
|
||||
}
|
||||
|
||||
_requiresPrevSourceCleanup(mbMap: MbMap): boolean {
|
||||
const mbSource = mbMap.getSource(this.getMbSourceId()) as RasterTileSource;
|
||||
if (!mbSource) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const sourceDataRequest = this.getSourceDataRequest();
|
||||
if (!sourceDataRequest) {
|
||||
return false;
|
||||
}
|
||||
const sourceData = sourceDataRequest.getData() as RasterTileSourceData | undefined;
|
||||
if (!sourceData) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return mbSource.tiles?.[0] !== sourceData.url;
|
||||
}
|
||||
|
||||
syncLayerWithMB(mbMap: MbMap) {
|
||||
this._removeStaleMbSourcesAndLayers(mbMap);
|
||||
const source = mbMap.getSource(this.getId());
|
||||
const mbLayerId = this._getMbLayerId();
|
||||
|
||||
|
@ -135,4 +176,8 @@ export class RasterTileLayer extends AbstractLayer {
|
|||
isBasemap(order: number) {
|
||||
return order === 0;
|
||||
}
|
||||
|
||||
async isFilteredByGlobalTime(): Promise<boolean> {
|
||||
return this.getSource().getApplyGlobalTime() && (await this.getSource().isTimeAware());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { DataFilters } from '../../../../common/descriptor_types';
|
||||
import { ISource } from '../source';
|
||||
|
||||
export interface ITMSSource extends ISource {
|
||||
getUrlTemplate(): Promise<string>;
|
||||
getUrlTemplate(dataFilters: DataFilters): Promise<string>;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ export type { MapEmbeddable, MapEmbeddableInput, MapEmbeddableOutput } from './e
|
|||
|
||||
export type { EMSTermJoinConfig, SampleValuesConfig } from './ems_autosuggest';
|
||||
|
||||
export type { ITMSSource } from './classes/sources/tms_source';
|
||||
|
||||
export type {
|
||||
GetFeatureActionsArgs,
|
||||
IVectorSource,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue