mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Migrate legacy maps service to NP & update refs (#60942)
* Get legacy maps into basic NP plugin form. Swap out legacy services for NP * Pull service settings from injected vars. Return new instance of service settings from setup * Use NP service settings in vega maps. Clean up legacy shim * Use NP maps service in region maps. Clean up shim. Add exports to NP service * Pull zoom precision out to separate module since it's dependent on config * Update paths to point to NP resources * More path updates, clean up, use IServiceSettings * Remove dependency on legacy service settings. Add tile_map dependency ng-sanitize * More path cleanup. Use zoomPrecision provided through plugin inteface * Move getPrecision into contract-provided function since it depends on config * Move tests to new service location, remove vis dir * Update test paths. Move origin const declaration into public * Clean up, fixes * Fix type errors. General cleaning * Inject toast service into map when needed * Fix typo in regionmap config * i18n fixes * Update jest test path * Fix karma tests * i18n fixes * Type updates. Add mapsLegacy to np karma mock * Remove html sanitizer * Fix vega test that depends on serviceSettings * Revise xpack license handling to use NP serviceSettings. Remove angular bindings Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
0666dbd35f
commit
6f46e6b827
70 changed files with 733 additions and 492 deletions
|
@ -24,6 +24,7 @@
|
|||
"src/legacy/core_plugins/management",
|
||||
"src/plugins/management"
|
||||
],
|
||||
"maps_legacy": "src/plugins/maps_legacy",
|
||||
"indexPatternManagement": "src/plugins/index_pattern_management",
|
||||
"advancedSettings": "src/plugins/advanced_settings",
|
||||
"kibana_legacy": "src/plugins/kibana_legacy",
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
@import './visualize/index';
|
||||
// Has to come after visualize because of some
|
||||
// bad cascading in the Editor layout
|
||||
@import 'src/legacy/ui/public/vis/index';
|
||||
@import '../../../../plugins/maps_legacy/public/index';
|
||||
|
||||
// Home styles
|
||||
@import '../../../../plugins/home/public/application/index';
|
||||
|
|
|
@ -23,12 +23,18 @@ import _ from 'lodash';
|
|||
import ChoroplethLayer from '../choropleth_layer';
|
||||
import { ImageComparator } from 'test_utils/image_comparator';
|
||||
import worldJson from './world.json';
|
||||
import EMS_CATALOGUE from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_manifest.json';
|
||||
import EMS_FILES from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_files.json';
|
||||
import EMS_TILES from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_tiles.json';
|
||||
import EMS_STYLE_ROAD_MAP_BRIGHT from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_bright';
|
||||
import EMS_STYLE_ROAD_MAP_DESATURATED from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_desaturated';
|
||||
import EMS_STYLE_DARK_MAP from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_dark';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import EMS_CATALOGUE from '../../../../../plugins/maps_legacy/public/__tests__/map/ems_mocks/sample_manifest.json';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import EMS_FILES from '../../../../../plugins/maps_legacy/public/__tests__/map/ems_mocks/sample_files.json';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import EMS_TILES from '../../../../../plugins/maps_legacy/public/__tests__/map/ems_mocks/sample_tiles.json';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import EMS_STYLE_ROAD_MAP_BRIGHT from '../../../../../plugins/maps_legacy/public/__tests__/map/ems_mocks/sample_style_bright';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import EMS_STYLE_ROAD_MAP_DESATURATED from '../../../../../plugins/maps_legacy/public/__tests__/map/ems_mocks/sample_style_desaturated';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import EMS_STYLE_DARK_MAP from '../../../../../plugins/maps_legacy/public/__tests__/map/ems_mocks/sample_style_dark';
|
||||
|
||||
import initialPng from './initial.png';
|
||||
import toiso3Png from './toiso3.png';
|
||||
|
@ -44,6 +50,10 @@ import { createRegionMapTypeDefinition } from '../region_map_type';
|
|||
import { ExprVis } from '../../../../../plugins/visualizations/public/expressions/vis';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { BaseVisType } from '../../../../../plugins/visualizations/public/vis_types/base_vis_type';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { setInjectedVarFunc } from '../../../../../plugins/maps_legacy/public/kibana_services';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { ServiceSettings } from '../../../../../plugins/maps_legacy/public/map/service_settings';
|
||||
|
||||
const THRESHOLD = 0.45;
|
||||
const PIXEL_DIFF = 96;
|
||||
|
@ -92,7 +102,31 @@ describe('RegionMapsVisualizationTests', function() {
|
|||
let getManifestStub;
|
||||
beforeEach(
|
||||
ngMock.inject((Private, $injector) => {
|
||||
const serviceSettings = $injector.get('serviceSettings');
|
||||
setInjectedVarFunc(injectedVar => {
|
||||
switch (injectedVar) {
|
||||
case 'mapConfig':
|
||||
return {
|
||||
emsFileApiUrl: '',
|
||||
emsTileApiUrl: '',
|
||||
emsLandingPageUrl: '',
|
||||
};
|
||||
case 'tilemapsConfig':
|
||||
return {
|
||||
deprecated: {
|
||||
config: {
|
||||
options: {
|
||||
attribution: '123',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
case 'version':
|
||||
return '123';
|
||||
default:
|
||||
return 'not found';
|
||||
}
|
||||
});
|
||||
const serviceSettings = new ServiceSettings();
|
||||
const uiSettings = $injector.get('config');
|
||||
const regionmapsConfig = {
|
||||
includeElasticMapsService: true,
|
||||
|
|
|
@ -22,11 +22,9 @@ import L from 'leaflet';
|
|||
import _ from 'lodash';
|
||||
import d3 from 'd3';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { KibanaMapLayer } from 'ui/vis/map/kibana_map_layer';
|
||||
import * as topojson from 'topojson-client';
|
||||
import { toastNotifications } from 'ui/notify';
|
||||
import * as colorUtil from 'ui/vis/map/color_util';
|
||||
|
||||
import { colorUtil, KibanaMapLayer } from '../../../../plugins/maps_legacy/public';
|
||||
import { truncatedColorMaps } from '../../../../plugins/charts/public';
|
||||
|
||||
const EMPTY_STYLE = {
|
||||
|
|
|
@ -21,9 +21,12 @@ import React, { useCallback, useMemo } from 'react';
|
|||
import { EuiIcon, EuiLink, EuiPanel, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import { FileLayerField, VectorLayer, ServiceSettings } from 'ui/vis/map/service_settings';
|
||||
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||
import {
|
||||
FileLayerField,
|
||||
VectorLayer,
|
||||
IServiceSettings,
|
||||
} from '../../../../../plugins/maps_legacy/public';
|
||||
import {
|
||||
NumberInputOption,
|
||||
SelectOption,
|
||||
|
@ -43,7 +46,7 @@ const mapFieldForOption = ({ description, name }: FileLayerField) => ({
|
|||
});
|
||||
|
||||
export type RegionMapOptionsProps = {
|
||||
serviceSettings: ServiceSettings;
|
||||
serviceSettings: IServiceSettings;
|
||||
} & VisOptionsProps<RegionMapVisParams>;
|
||||
|
||||
function RegionMapOptions(props: RegionMapOptionsProps) {
|
||||
|
|
|
@ -20,21 +20,18 @@
|
|||
import { PluginInitializerContext } from 'kibana/public';
|
||||
import { npSetup, npStart } from 'ui/new_platform';
|
||||
|
||||
import { RegionMapPluginSetupDependencies, RegionMapsConfig } from './plugin';
|
||||
import { RegionMapPluginSetupDependencies } from './plugin';
|
||||
import { LegacyDependenciesPlugin } from './shim';
|
||||
import { plugin } from '.';
|
||||
|
||||
const regionmapsConfig = npSetup.core.injectedMetadata.getInjectedVar(
|
||||
'regionmap'
|
||||
) as RegionMapsConfig;
|
||||
|
||||
const plugins: Readonly<RegionMapPluginSetupDependencies> = {
|
||||
expressions: npSetup.plugins.expressions,
|
||||
visualizations: npSetup.plugins.visualizations,
|
||||
mapsLegacy: npSetup.plugins.mapsLegacy,
|
||||
|
||||
// Temporary solution
|
||||
// It will be removed when all dependent services are migrated to the new platform.
|
||||
__LEGACY: new LegacyDependenciesPlugin(regionmapsConfig),
|
||||
__LEGACY: new LegacyDependenciesPlugin(),
|
||||
};
|
||||
|
||||
const pluginInstance = plugin({} as PluginInitializerContext);
|
||||
|
|
|
@ -32,10 +32,14 @@ import { LegacyDependenciesPlugin, LegacyDependenciesPluginSetup } from './shim'
|
|||
import { createRegionMapFn } from './region_map_fn';
|
||||
// @ts-ignore
|
||||
import { createRegionMapTypeDefinition } from './region_map_type';
|
||||
import { IServiceSettings, MapsLegacyPluginSetup } from '../../../../plugins/maps_legacy/public';
|
||||
|
||||
/** @private */
|
||||
interface RegionMapVisualizationDependencies extends LegacyDependenciesPluginSetup {
|
||||
uiSettings: IUiSettingsClient;
|
||||
regionmapsConfig: RegionMapsConfig;
|
||||
serviceSettings: IServiceSettings;
|
||||
notificationService: any;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
@ -43,6 +47,7 @@ export interface RegionMapPluginSetupDependencies {
|
|||
expressions: ReturnType<ExpressionsPublicPlugin['setup']>;
|
||||
visualizations: VisualizationsSetup;
|
||||
__LEGACY: LegacyDependenciesPlugin;
|
||||
mapsLegacy: MapsLegacyPluginSetup;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
@ -61,10 +66,13 @@ export class RegionMapPlugin implements Plugin<Promise<void>, void> {
|
|||
|
||||
public async setup(
|
||||
core: CoreSetup,
|
||||
{ expressions, visualizations, __LEGACY }: RegionMapPluginSetupDependencies
|
||||
{ expressions, visualizations, mapsLegacy, __LEGACY }: RegionMapPluginSetupDependencies
|
||||
) {
|
||||
const visualizationDependencies: Readonly<RegionMapVisualizationDependencies> = {
|
||||
uiSettings: core.uiSettings,
|
||||
regionmapsConfig: core.injectedMetadata.getInjectedVar('regionmap') as RegionMapsConfig,
|
||||
serviceSettings: mapsLegacy.serviceSettings,
|
||||
notificationService: core.notifications.toasts,
|
||||
...(await __LEGACY.setup()),
|
||||
};
|
||||
|
||||
|
|
|
@ -28,8 +28,16 @@ import { truncatedColorMaps } from '../../../../plugins/charts/public';
|
|||
// TODO: reference to TILE_MAP plugin should be removed
|
||||
import { BaseMapsVisualizationProvider } from '../../tile_map/public/base_maps_visualization';
|
||||
|
||||
export function createRegionMapVisualization({ serviceSettings, $injector, uiSettings }) {
|
||||
const BaseMapsVisualization = new BaseMapsVisualizationProvider(serviceSettings);
|
||||
export function createRegionMapVisualization({
|
||||
serviceSettings,
|
||||
$injector,
|
||||
uiSettings,
|
||||
notificationService,
|
||||
}) {
|
||||
const BaseMapsVisualization = new BaseMapsVisualizationProvider(
|
||||
serviceSettings,
|
||||
notificationService
|
||||
);
|
||||
const tooltipFormatter = new TileMapTooltipFormatter($injector);
|
||||
|
||||
return class RegionMapsVisualization extends BaseMapsVisualization {
|
||||
|
|
|
@ -19,31 +19,20 @@
|
|||
|
||||
import chrome from 'ui/chrome';
|
||||
import { CoreStart, Plugin } from 'kibana/public';
|
||||
import 'ui/vis/map/service_settings';
|
||||
import { RegionMapsConfig } from '../plugin';
|
||||
|
||||
/** @internal */
|
||||
export interface LegacyDependenciesPluginSetup {
|
||||
$injector: any;
|
||||
serviceSettings: any;
|
||||
regionmapsConfig: RegionMapsConfig;
|
||||
}
|
||||
|
||||
export class LegacyDependenciesPlugin
|
||||
implements Plugin<Promise<LegacyDependenciesPluginSetup>, void> {
|
||||
constructor(private readonly regionmapsConfig: RegionMapsConfig) {}
|
||||
|
||||
public async setup() {
|
||||
const $injector = await chrome.dangerouslyGetActiveInjector();
|
||||
|
||||
return {
|
||||
$injector,
|
||||
regionmapsConfig: this.regionmapsConfig,
|
||||
// Settings for EMSClient.
|
||||
// EMSClient, which currently lives in the tile_map vis,
|
||||
// will probably end up being exposed from the future vis_type_maps plugin,
|
||||
// which would register both the tile_map and the region_map vis plugins.
|
||||
serviceSettings: $injector.get('serviceSettings'),
|
||||
} as LegacyDependenciesPluginSetup;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { VectorLayer, FileLayerField } from 'ui/vis/map/service_settings';
|
||||
import { VectorLayer, FileLayerField } from '../../../../plugins/maps_legacy/public';
|
||||
import { WMSOptions } from '../../tile_map/public/types';
|
||||
|
||||
export interface RegionMapVisParams {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { FileLayer, VectorLayer } from 'ui/vis/map/service_settings';
|
||||
import { FileLayer, VectorLayer } from '../../../../plugins/maps_legacy/public';
|
||||
// TODO: reference to TILE_MAP plugin should be removed
|
||||
import { ORIGIN } from '../../../../legacy/core_plugins/tile_map/common/origin';
|
||||
|
||||
|
|
|
@ -25,12 +25,18 @@ import initial from './initial.png';
|
|||
import blues from './blues.png';
|
||||
import shadedGeohashGrid from './shadedGeohashGrid.png';
|
||||
import heatmapRaw from './heatmap_raw.png';
|
||||
import EMS_CATALOGUE from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_manifest.json';
|
||||
import EMS_FILES from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_files.json';
|
||||
import EMS_TILES from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_tiles.json';
|
||||
import EMS_STYLE_ROAD_MAP_BRIGHT from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_bright';
|
||||
import EMS_STYLE_ROAD_MAP_DESATURATED from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_desaturated';
|
||||
import EMS_STYLE_DARK_MAP from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_dark';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import EMS_CATALOGUE from '../../../../../plugins/maps_legacy/public/__tests__/map/ems_mocks/sample_manifest.json';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import EMS_FILES from '../../../../../plugins/maps_legacy/public/__tests__/map/ems_mocks/sample_files.json';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import EMS_TILES from '../../../../../plugins/maps_legacy/public/__tests__/map/ems_mocks/sample_tiles.json';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import EMS_STYLE_ROAD_MAP_BRIGHT from '../../../../../plugins/maps_legacy/public/__tests__/map/ems_mocks/sample_style_bright';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import EMS_STYLE_ROAD_MAP_DESATURATED from '../../../../../plugins/maps_legacy/public/__tests__/map/ems_mocks/sample_style_desaturated';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import EMS_STYLE_DARK_MAP from '../../../../../plugins/maps_legacy/public/__tests__/map/ems_mocks/sample_style_dark';
|
||||
|
||||
import { createTileMapVisualization } from '../tile_map_visualization';
|
||||
import { createTileMapTypeDefinition } from '../tile_map_type';
|
||||
|
@ -38,6 +44,15 @@ import { createTileMapTypeDefinition } from '../tile_map_type';
|
|||
import { ExprVis } from '../../../../../plugins/visualizations/public/expressions/vis';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { BaseVisType } from '../../../../../plugins/visualizations/public/vis_types/base_vis_type';
|
||||
import {
|
||||
getPrecision,
|
||||
getZoomPrecision,
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
} from '../../../../../plugins/maps_legacy/public/map/precision';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { ServiceSettings } from '../../../../../plugins/maps_legacy/public/map/service_settings';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { setInjectedVarFunc } from '../../../../../plugins/maps_legacy/public/kibana_services';
|
||||
|
||||
function mockRawData() {
|
||||
const stack = [dummyESResponse];
|
||||
|
@ -75,13 +90,39 @@ describe('CoordinateMapsVisualizationTest', function() {
|
|||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(
|
||||
ngMock.inject((Private, $injector) => {
|
||||
const serviceSettings = $injector.get('serviceSettings');
|
||||
setInjectedVarFunc(injectedVar => {
|
||||
switch (injectedVar) {
|
||||
case 'mapConfig':
|
||||
return {
|
||||
emsFileApiUrl: '',
|
||||
emsTileApiUrl: '',
|
||||
emsLandingPageUrl: '',
|
||||
};
|
||||
case 'tilemapsConfig':
|
||||
return {
|
||||
deprecated: {
|
||||
config: {
|
||||
options: {
|
||||
attribution: '123',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
case 'version':
|
||||
return '123';
|
||||
default:
|
||||
return 'not found';
|
||||
}
|
||||
});
|
||||
const serviceSettings = new ServiceSettings();
|
||||
const uiSettings = $injector.get('config');
|
||||
|
||||
dependencies = {
|
||||
serviceSettings,
|
||||
uiSettings,
|
||||
$injector,
|
||||
getPrecision,
|
||||
getZoomPrecision,
|
||||
};
|
||||
|
||||
visType = new BaseVisType(createTileMapTypeDefinition(dependencies));
|
||||
|
|
|
@ -18,13 +18,13 @@
|
|||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { KibanaMap } from 'ui/vis/map/kibana_map';
|
||||
import { GeohashLayer } from '../geohash_layer';
|
||||
// import heatmapPng from './heatmap.png';
|
||||
import scaledCircleMarkersPng from './scaledCircleMarkers.png';
|
||||
// import shadedCircleMarkersPng from './shadedCircleMarkers.png';
|
||||
import { ImageComparator } from 'test_utils/image_comparator';
|
||||
import GeoHashSampleData from './dummy_es_response.json';
|
||||
import { KibanaMap } from '../../../../../plugins/maps_legacy/public';
|
||||
|
||||
describe('geohash_layer', function() {
|
||||
let domNode;
|
||||
|
|
|
@ -19,22 +19,25 @@
|
|||
|
||||
import _ from 'lodash';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { KibanaMap } from 'ui/vis/map/kibana_map';
|
||||
import { KibanaMap } from '../../../../plugins/maps_legacy/public';
|
||||
import * as Rx from 'rxjs';
|
||||
import { filter, first } from 'rxjs/operators';
|
||||
import 'ui/vis/map/service_settings';
|
||||
import { toastNotifications } from 'ui/notify';
|
||||
import chrome from 'ui/chrome';
|
||||
|
||||
const WMS_MINZOOM = 0;
|
||||
const WMS_MAXZOOM = 22; //increase this to 22. Better for WMS
|
||||
|
||||
export function BaseMapsVisualizationProvider(serviceSettings) {
|
||||
export function BaseMapsVisualizationProvider(mapServiceSettings, notificationService) {
|
||||
/**
|
||||
* Abstract base class for a visualization consisting of a map with a single baselayer.
|
||||
* @class BaseMapsVisualization
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
const serviceSettings = mapServiceSettings;
|
||||
const toastService = notificationService;
|
||||
|
||||
return class BaseMapsVisualization {
|
||||
constructor(element, vis) {
|
||||
this.vis = vis;
|
||||
|
@ -94,8 +97,9 @@ export function BaseMapsVisualizationProvider(serviceSettings) {
|
|||
const centerFromUIState = uiState.get('mapCenter');
|
||||
options.zoom = !isNaN(zoomFromUiState) ? zoomFromUiState : this.vis.params.mapZoom;
|
||||
options.center = centerFromUIState ? centerFromUIState : this.vis.params.mapCenter;
|
||||
const services = { toastService };
|
||||
|
||||
this._kibanaMap = new KibanaMap(this._container, options);
|
||||
this._kibanaMap = new KibanaMap(this._container, options, services);
|
||||
this._kibanaMap.setMinZoom(WMS_MINZOOM); //use a default
|
||||
this._kibanaMap.setMaxZoom(WMS_MAXZOOM); //use a default
|
||||
|
||||
|
|
|
@ -21,8 +21,7 @@ import React, { useMemo } from 'react';
|
|||
import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import { TmsLayer } from 'ui/vis/map/service_settings';
|
||||
import { TmsLayer } from '../../../../../plugins/maps_legacy/public';
|
||||
import { Vis } from '../../../../../plugins/visualizations/public';
|
||||
import { RegionMapVisParams } from '../../../region_map/public/types';
|
||||
import { SelectOption, SwitchOption } from '../../../../../plugins/charts/public';
|
||||
|
|
|
@ -20,8 +20,7 @@
|
|||
import L from 'leaflet';
|
||||
import { min, isEqual } from 'lodash';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { KibanaMapLayer } from 'ui/vis/map/kibana_map_layer';
|
||||
import { KibanaMapLayer } from '../../../../plugins/maps_legacy/public';
|
||||
import { HeatmapMarkers } from './markers/heatmap';
|
||||
import { ScaledCirclesMarkers } from './markers/scaled_circles';
|
||||
import { ShadedCirclesMarkers } from './markers/shaded_circles';
|
||||
|
|
|
@ -27,6 +27,7 @@ import { plugin } from '.';
|
|||
const plugins: Readonly<TileMapPluginSetupDependencies> = {
|
||||
expressions: npSetup.plugins.expressions,
|
||||
visualizations: npSetup.plugins.visualizations,
|
||||
mapsLegacy: npSetup.plugins.mapsLegacy,
|
||||
|
||||
// Temporary solution
|
||||
// It will be removed when all dependent services are migrated to the new platform.
|
||||
|
|
|
@ -22,8 +22,7 @@ import _ from 'lodash';
|
|||
import d3 from 'd3';
|
||||
import $ from 'jquery';
|
||||
import { EventEmitter } from 'events';
|
||||
import * as colorUtil from 'ui/vis/map/color_util';
|
||||
|
||||
import { colorUtil } from '../../../../../plugins/maps_legacy/public';
|
||||
import { truncatedColorMaps } from '../../../../../plugins/charts/public';
|
||||
|
||||
export class ScaledCirclesMarkers extends EventEmitter {
|
||||
|
|
|
@ -32,16 +32,22 @@ import { LegacyDependenciesPlugin, LegacyDependenciesPluginSetup } from './shim'
|
|||
import { createTileMapFn } from './tile_map_fn';
|
||||
// @ts-ignore
|
||||
import { createTileMapTypeDefinition } from './tile_map_type';
|
||||
import { IServiceSettings, MapsLegacyPluginSetup } from '../../../../plugins/maps_legacy/public';
|
||||
|
||||
/** @private */
|
||||
interface TileMapVisualizationDependencies extends LegacyDependenciesPluginSetup {
|
||||
serviceSettings: IServiceSettings;
|
||||
uiSettings: IUiSettingsClient;
|
||||
getZoomPrecision: any;
|
||||
getPrecision: any;
|
||||
notificationService: any;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface TileMapPluginSetupDependencies {
|
||||
expressions: ReturnType<ExpressionsPublicPlugin['setup']>;
|
||||
visualizations: VisualizationsSetup;
|
||||
mapsLegacy: MapsLegacyPluginSetup;
|
||||
__LEGACY: LegacyDependenciesPlugin;
|
||||
}
|
||||
|
||||
|
@ -55,9 +61,14 @@ export class TileMapPlugin implements Plugin<Promise<void>, void> {
|
|||
|
||||
public async setup(
|
||||
core: CoreSetup,
|
||||
{ expressions, visualizations, __LEGACY }: TileMapPluginSetupDependencies
|
||||
{ expressions, visualizations, mapsLegacy, __LEGACY }: TileMapPluginSetupDependencies
|
||||
) {
|
||||
const { getZoomPrecision, getPrecision, serviceSettings } = mapsLegacy;
|
||||
const visualizationDependencies: Readonly<TileMapVisualizationDependencies> = {
|
||||
serviceSettings,
|
||||
getZoomPrecision,
|
||||
getPrecision,
|
||||
notificationService: core.notifications.toasts,
|
||||
uiSettings: core.uiSettings,
|
||||
...(await __LEGACY.setup()),
|
||||
};
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
*/
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
import 'ui/vis/map/service_settings';
|
||||
import { CoreStart, Plugin } from 'kibana/public';
|
||||
// TODO: Determine why visualizations don't populate without this
|
||||
import 'angular-sanitize';
|
||||
|
||||
/** @internal */
|
||||
export interface LegacyDependenciesPluginSetup {
|
||||
serviceSettings: any;
|
||||
$injector: any;
|
||||
}
|
||||
|
||||
|
@ -34,11 +34,6 @@ export class LegacyDependenciesPlugin
|
|||
|
||||
return {
|
||||
$injector,
|
||||
// Settings for EMSClient.
|
||||
// EMSClient, which currently lives in the tile_map vis,
|
||||
// will probably end up being exposed from the future vis_type_maps plugin,
|
||||
// which would register both the tile_map and the region_map vis plugins.
|
||||
serviceSettings: $injector.get('serviceSettings'),
|
||||
} as LegacyDependenciesPluginSetup;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { convertToGeoJson } from 'ui/vis/map/convert_to_geojson';
|
||||
import { convertToGeoJson } from '../../../../plugins/maps_legacy/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const createTileMapFn = () => ({
|
||||
|
|
|
@ -19,9 +19,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { convertToGeoJson } from 'ui/vis/map/convert_to_geojson';
|
||||
|
||||
import { convertToGeoJson } from '../../../../plugins/maps_legacy/public';
|
||||
import { Schemas } from '../../../../plugins/vis_default_editor/public';
|
||||
import { createTileMapVisualization } from './tile_map_visualization';
|
||||
import { TileMapOptions } from './components/tile_map_options';
|
||||
|
|
|
@ -23,15 +23,19 @@ import { BaseMapsVisualizationProvider } from './base_maps_visualization';
|
|||
import { TileMapTooltipFormatterProvider } from './editors/_tooltip_formatter';
|
||||
import { npStart } from 'ui/new_platform';
|
||||
import { getFormat } from '../../../ui/public/visualize/loader/pipeline_helpers/utilities';
|
||||
import {
|
||||
scaleBounds,
|
||||
zoomPrecision,
|
||||
getPrecision,
|
||||
geoContains,
|
||||
} from '../../../ui/public/vis/map/decode_geo_hash';
|
||||
import { scaleBounds, geoContains } from '../../../../plugins/maps_legacy/public';
|
||||
|
||||
export const createTileMapVisualization = ({ serviceSettings, $injector }) => {
|
||||
const BaseMapsVisualization = new BaseMapsVisualizationProvider(serviceSettings);
|
||||
export const createTileMapVisualization = ({
|
||||
serviceSettings,
|
||||
$injector,
|
||||
getZoomPrecision,
|
||||
getPrecision,
|
||||
notificationService,
|
||||
}) => {
|
||||
const BaseMapsVisualization = new BaseMapsVisualizationProvider(
|
||||
serviceSettings,
|
||||
notificationService
|
||||
);
|
||||
const tooltipFormatter = new TileMapTooltipFormatterProvider($injector);
|
||||
|
||||
return class CoordinateMapsVisualization extends BaseMapsVisualization {
|
||||
|
@ -59,6 +63,7 @@ export const createTileMapVisualization = ({ serviceSettings, $injector }) => {
|
|||
updateVarsObject.data.boundingBox = geohashAgg.aggConfigParams.boundingBox;
|
||||
}
|
||||
// todo: autoPrecision should be vis parameter, not aggConfig one
|
||||
const zoomPrecision = getZoomPrecision();
|
||||
updateVarsObject.data.precision = geohashAgg.aggConfigParams.autoPrecision
|
||||
? zoomPrecision[this.vis.getUiState().get('mapZoom')]
|
||||
: getPrecision(geohashAgg.aggConfigParams.precision);
|
||||
|
|
|
@ -22,7 +22,7 @@ import { functionWrapper } from '../../../../plugins/expressions/common/expressi
|
|||
import { createTileMapFn } from './tile_map_fn';
|
||||
|
||||
jest.mock('ui/new_platform');
|
||||
jest.mock('ui/vis/map/convert_to_geojson', () => ({
|
||||
jest.mock('../../../../plugins/maps_legacy/public', () => ({
|
||||
convertToGeoJson: jest.fn().mockReturnValue({
|
||||
featureCollection: {
|
||||
type: 'FeatureCollection',
|
||||
|
@ -37,7 +37,7 @@ jest.mock('ui/vis/map/convert_to_geojson', () => ({
|
|||
}),
|
||||
}));
|
||||
|
||||
import { convertToGeoJson } from 'ui/vis/map/convert_to_geojson';
|
||||
import { convertToGeoJson } from '../../../../plugins/maps_legacy/public';
|
||||
|
||||
describe('interpreter/functions#tilemap', () => {
|
||||
const fn = functionWrapper(createTileMapFn());
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { TmsLayer } from 'ui/vis/map/service_settings';
|
||||
import { TmsLayer } from '../../../../plugins/maps_legacy/public';
|
||||
import { MapTypes } from './map_types';
|
||||
|
||||
export interface WMSOptions {
|
||||
|
|
|
@ -21,7 +21,6 @@ import 'ngreact';
|
|||
import 'brace/mode/hjson';
|
||||
import 'brace/ext/searchbox';
|
||||
import 'ui/accessibility/kbn_ui_ace_keyboard_mode';
|
||||
import 'ui/vis/map/service_settings';
|
||||
|
||||
import { once } from 'lodash';
|
||||
// @ts-ignore
|
||||
|
|
|
@ -49,6 +49,10 @@ import { BaseVisType } from '../../../../../plugins/visualizations/public/vis_ty
|
|||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { ExprVis } from '../../../../../plugins/visualizations/public/expressions/vis';
|
||||
import { setInjectedVars } from '../services';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { setInjectedVarFunc } from '../../../../../plugins/maps_legacy/public/kibana_services';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { ServiceSettings } from '../../../../../plugins/maps_legacy/public/map/service_settings';
|
||||
|
||||
const THRESHOLD = 0.1;
|
||||
const PIXEL_DIFF = 30;
|
||||
|
@ -69,9 +73,34 @@ describe('VegaVisualizations', () => {
|
|||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(
|
||||
ngMock.inject($injector => {
|
||||
ngMock.inject(() => {
|
||||
setInjectedVarFunc(injectedVar => {
|
||||
switch (injectedVar) {
|
||||
case 'mapConfig':
|
||||
return {
|
||||
emsFileApiUrl: '',
|
||||
emsTileApiUrl: '',
|
||||
emsLandingPageUrl: '',
|
||||
};
|
||||
case 'tilemapsConfig':
|
||||
return {
|
||||
deprecated: {
|
||||
config: {
|
||||
options: {
|
||||
attribution: '123',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
case 'version':
|
||||
return '123';
|
||||
default:
|
||||
return 'not found';
|
||||
}
|
||||
});
|
||||
const serviceSettings = new ServiceSettings();
|
||||
vegaVisualizationDependencies = {
|
||||
serviceSettings: $injector.get('serviceSettings'),
|
||||
serviceSettings,
|
||||
core: {
|
||||
uiSettings: npStart.core.uiSettings,
|
||||
},
|
||||
|
|
|
@ -20,16 +20,12 @@
|
|||
import { PluginInitializerContext } from 'kibana/public';
|
||||
import { npSetup, npStart } from 'ui/new_platform';
|
||||
import { VegaPluginSetupDependencies, VegaPluginStartDependencies } from './plugin';
|
||||
import { LegacyDependenciesPlugin } from './shim';
|
||||
import { plugin } from '.';
|
||||
|
||||
const setupPlugins: Readonly<VegaPluginSetupDependencies> = {
|
||||
...npSetup.plugins,
|
||||
visualizations: npSetup.plugins.visualizations,
|
||||
|
||||
// Temporary solution
|
||||
// It will be removed when all dependent services are migrated to the new platform.
|
||||
__LEGACY: new LegacyDependenciesPlugin(),
|
||||
mapsLegacy: npSetup.plugins.mapsLegacy,
|
||||
};
|
||||
|
||||
const startPlugins: Readonly<VegaPluginStartDependencies> = {
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
* under the License.
|
||||
*/
|
||||
import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '../../../../core/public';
|
||||
import { LegacyDependenciesPlugin, LegacyDependenciesPluginSetup } from './shim';
|
||||
import { Plugin as ExpressionsPublicPlugin } from '../../../../plugins/expressions/public';
|
||||
import { Plugin as DataPublicPlugin } from '../../../../plugins/data/public';
|
||||
import { VisualizationsSetup } from '../../../../plugins/visualizations/public';
|
||||
|
@ -32,13 +31,15 @@ import {
|
|||
import { createVegaFn } from './vega_fn';
|
||||
import { createVegaTypeDefinition } from './vega_type';
|
||||
import { VisTypeVegaSetup } from '../../../../plugins/vis_type_vega/public';
|
||||
import { IServiceSettings } from '../../../../plugins/maps_legacy/public';
|
||||
|
||||
/** @internal */
|
||||
export interface VegaVisualizationDependencies extends LegacyDependenciesPluginSetup {
|
||||
export interface VegaVisualizationDependencies {
|
||||
core: CoreSetup;
|
||||
plugins: {
|
||||
data: ReturnType<DataPublicPlugin['setup']>;
|
||||
};
|
||||
serviceSettings: IServiceSettings;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
@ -47,7 +48,7 @@ export interface VegaPluginSetupDependencies {
|
|||
visualizations: VisualizationsSetup;
|
||||
data: ReturnType<DataPublicPlugin['setup']>;
|
||||
visTypeVega: VisTypeVegaSetup;
|
||||
__LEGACY: LegacyDependenciesPlugin;
|
||||
mapsLegacy: any;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
@ -65,7 +66,7 @@ export class VegaPlugin implements Plugin<Promise<void>, void> {
|
|||
|
||||
public async setup(
|
||||
core: CoreSetup,
|
||||
{ data, expressions, visualizations, visTypeVega, __LEGACY }: VegaPluginSetupDependencies
|
||||
{ data, expressions, visualizations, visTypeVega, mapsLegacy }: VegaPluginSetupDependencies
|
||||
) {
|
||||
setInjectedVars({
|
||||
enableExternalUrls: visTypeVega.config.enableExternalUrls,
|
||||
|
@ -79,7 +80,7 @@ export class VegaPlugin implements Plugin<Promise<void>, void> {
|
|||
plugins: {
|
||||
data,
|
||||
},
|
||||
...(await __LEGACY.setup()),
|
||||
serviceSettings: mapsLegacy.serviceSettings,
|
||||
};
|
||||
|
||||
expressions.registerFunction(() => createVegaFn(visualizationDependencies));
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
// TODO remove this file as soon as serviceSettings is exposed in the new platform
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import chrome from 'ui/chrome';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import 'ui/vis/map/service_settings';
|
||||
import { CoreStart, Plugin } from 'kibana/public';
|
||||
|
||||
/** @internal */
|
||||
export interface LegacyDependenciesPluginSetup {
|
||||
serviceSettings: any;
|
||||
}
|
||||
|
||||
export class LegacyDependenciesPlugin
|
||||
implements Plugin<Promise<LegacyDependenciesPluginSetup>, void> {
|
||||
public async setup() {
|
||||
const $injector = await chrome.dangerouslyGetActiveInjector();
|
||||
|
||||
return {
|
||||
// Settings for EMSClient.
|
||||
// EMSClient, which currently lives in the tile_map vis,
|
||||
// will probably end up being exposed from the future vis_type_maps plugin,
|
||||
// which would register both the tile_map and the region_map vis plugins.
|
||||
serviceSettings: $injector.get('serviceSettings'),
|
||||
} as LegacyDependenciesPluginSetup;
|
||||
}
|
||||
|
||||
public start(core: CoreStart) {
|
||||
// nothing to do here yet
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import L from 'leaflet';
|
||||
import 'leaflet-vega';
|
||||
import { KibanaMapLayer } from '../legacy_imports';
|
||||
import { KibanaMapLayer } from '../../../../../plugins/maps_legacy/public';
|
||||
|
||||
export class VegaMapLayer extends KibanaMapLayer {
|
||||
constructor(spec, options) {
|
||||
|
|
|
@ -21,10 +21,15 @@ import * as vega from 'vega-lib';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { VegaBaseView } from './vega_base_view';
|
||||
import { VegaMapLayer } from './vega_map_layer';
|
||||
import { KibanaMap } from '../legacy_imports';
|
||||
import { KibanaMap } from '../../../../../plugins/maps_legacy/public';
|
||||
import { getEmsTileLayerId, getUISettings } from '../services';
|
||||
|
||||
export class VegaMapView extends VegaBaseView {
|
||||
constructor(opts, services) {
|
||||
super(opts);
|
||||
this.services = services;
|
||||
}
|
||||
|
||||
async _initViewCustomizations() {
|
||||
const mapConfig = this._parser.mapConfig;
|
||||
let baseMapOpts;
|
||||
|
@ -102,14 +107,18 @@ export class VegaMapView extends VegaBaseView {
|
|||
// maxBounds = L.latLngBounds(L.latLng(b[1], b[0]), L.latLng(b[3], b[2]));
|
||||
// }
|
||||
|
||||
this._kibanaMap = new KibanaMap(this._$container.get(0), {
|
||||
zoom,
|
||||
minZoom,
|
||||
maxZoom,
|
||||
center: [mapConfig.latitude, mapConfig.longitude],
|
||||
zoomControl: mapConfig.zoomControl,
|
||||
scrollWheelZoom: mapConfig.scrollWheelZoom,
|
||||
});
|
||||
this._kibanaMap = new KibanaMap(
|
||||
this._$container.get(0),
|
||||
{
|
||||
zoom,
|
||||
minZoom,
|
||||
maxZoom,
|
||||
center: [mapConfig.latitude, mapConfig.longitude],
|
||||
zoomControl: mapConfig.zoomControl,
|
||||
scrollWheelZoom: mapConfig.scrollWheelZoom,
|
||||
},
|
||||
this.services
|
||||
);
|
||||
|
||||
if (baseMapOpts) {
|
||||
this._kibanaMap.setBaseLayer({
|
||||
|
|
|
@ -116,7 +116,8 @@ export const createVegaVisualization = ({ serviceSettings }) =>
|
|||
};
|
||||
|
||||
if (vegaParser.useMap) {
|
||||
this._vegaView = new VegaMapView(vegaViewParams);
|
||||
const services = { toastService: getNotifications().toasts };
|
||||
this._vegaView = new VegaMapView(vegaViewParams, services);
|
||||
} else {
|
||||
this._vegaView = new VegaView(vegaViewParams);
|
||||
}
|
||||
|
|
|
@ -309,6 +309,12 @@ export const npSetup = {
|
|||
registerAlias: sinon.fake(),
|
||||
hideTypes: sinon.fake(),
|
||||
},
|
||||
|
||||
mapsLegacy: {
|
||||
serviceSettings: sinon.fake(),
|
||||
getPrecision: sinon.fake(),
|
||||
getZoomPrecision: sinon.fake(),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ import {
|
|||
VisualizationsSetup,
|
||||
VisualizationsStart,
|
||||
} from '../../../../plugins/visualizations/public';
|
||||
import { MapsLegacyPluginSetup } from '../../../../plugins/maps_legacy/public';
|
||||
|
||||
export interface PluginsSetup {
|
||||
bfetch: BfetchPublicSetup;
|
||||
|
@ -90,6 +91,7 @@ export interface PluginsSetup {
|
|||
visualizations: VisualizationsSetup;
|
||||
telemetry?: TelemetryPluginSetup;
|
||||
savedObjectsManagement: SavedObjectsManagementPluginSetup;
|
||||
mapsLegacy: MapsLegacyPluginSetup;
|
||||
indexPatternManagement: IndexPatternManagementSetup;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,256 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { uiModules } from '../../modules';
|
||||
import _ from 'lodash';
|
||||
import MarkdownIt from 'markdown-it';
|
||||
import { ORIGIN } from '../../../../core_plugins/tile_map/common/origin';
|
||||
import { EMSClient } from '@elastic/ems-client';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import 'angular-sanitize';
|
||||
|
||||
const markdownIt = new MarkdownIt({
|
||||
html: false,
|
||||
linkify: true,
|
||||
});
|
||||
|
||||
const TMS_IN_YML_ID = 'TMS in config/kibana.yml';
|
||||
|
||||
uiModules
|
||||
.get('kibana', ['ngSanitize'])
|
||||
.service('serviceSettings', function($sanitize, mapConfig, tilemapsConfig, kbnVersion) {
|
||||
const attributionFromConfig = $sanitize(
|
||||
markdownIt.render(tilemapsConfig.deprecated.config.options.attribution || '')
|
||||
);
|
||||
const tmsOptionsFromConfig = _.assign({}, tilemapsConfig.deprecated.config.options, {
|
||||
attribution: attributionFromConfig,
|
||||
});
|
||||
|
||||
class ServiceSettings {
|
||||
constructor() {
|
||||
this._showZoomMessage = true;
|
||||
this._emsClient = new EMSClient({
|
||||
language: i18n.getLocale(),
|
||||
appVersion: kbnVersion,
|
||||
appName: 'kibana',
|
||||
fileApiUrl: mapConfig.emsFileApiUrl,
|
||||
tileApiUrl: mapConfig.emsTileApiUrl,
|
||||
htmlSanitizer: $sanitize,
|
||||
landingPageUrl: mapConfig.emsLandingPageUrl,
|
||||
// Wrap to avoid errors passing window fetch
|
||||
fetchFunction: function(...args) {
|
||||
return fetch(...args);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
shouldShowZoomMessage({ origin }) {
|
||||
return origin === ORIGIN.EMS && this._showZoomMessage;
|
||||
}
|
||||
|
||||
disableZoomMessage() {
|
||||
this._showZoomMessage = false;
|
||||
}
|
||||
|
||||
__debugStubManifestCalls(manifestRetrieval) {
|
||||
const oldGetManifest = this._emsClient.getManifest;
|
||||
this._emsClient.getManifest = manifestRetrieval;
|
||||
return {
|
||||
removeStub: () => {
|
||||
delete this._emsClient.getManifest;
|
||||
//not strictly necessary since this is prototype method
|
||||
if (this._emsClient.getManifest !== oldGetManifest) {
|
||||
this._emsClient.getManifest = oldGetManifest;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async getFileLayers() {
|
||||
if (!mapConfig.includeElasticMapsService) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const fileLayers = await this._emsClient.getFileLayers();
|
||||
return fileLayers.map(fileLayer => {
|
||||
//backfill to older settings
|
||||
const format = fileLayer.getDefaultFormatType();
|
||||
const meta = fileLayer.getDefaultFormatMeta();
|
||||
|
||||
return {
|
||||
name: fileLayer.getDisplayName(),
|
||||
origin: fileLayer.getOrigin(),
|
||||
id: fileLayer.getId(),
|
||||
created_at: fileLayer.getCreatedAt(),
|
||||
attribution: fileLayer.getHTMLAttribution(),
|
||||
fields: fileLayer.getFieldsInLanguage(),
|
||||
format: format, //legacy: format and meta are split up
|
||||
meta: meta, //legacy, format and meta are split up
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the services published by EMS (if configures)
|
||||
* It also includes the service configured in tilemap (override)
|
||||
*/
|
||||
async getTMSServices() {
|
||||
let allServices = [];
|
||||
if (tilemapsConfig.deprecated.isOverridden) {
|
||||
//use tilemap.* settings from yml
|
||||
const tmsService = _.cloneDeep(tmsOptionsFromConfig);
|
||||
tmsService.id = TMS_IN_YML_ID;
|
||||
tmsService.origin = ORIGIN.KIBANA_YML;
|
||||
allServices.push(tmsService);
|
||||
}
|
||||
|
||||
if (mapConfig.includeElasticMapsService) {
|
||||
const servicesFromManifest = await this._emsClient.getTMSServices();
|
||||
const strippedServiceFromManifest = await Promise.all(
|
||||
servicesFromManifest
|
||||
.filter(tmsService => tmsService.getId() === mapConfig.emsTileLayerId.bright)
|
||||
.map(async tmsService => {
|
||||
//shim for compatibility
|
||||
const shim = {
|
||||
origin: tmsService.getOrigin(),
|
||||
id: tmsService.getId(),
|
||||
minZoom: await tmsService.getMinZoom(),
|
||||
maxZoom: await tmsService.getMaxZoom(),
|
||||
attribution: tmsService.getHTMLAttribution(),
|
||||
};
|
||||
return shim;
|
||||
})
|
||||
);
|
||||
allServices = allServices.concat(strippedServiceFromManifest);
|
||||
}
|
||||
|
||||
return allServices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add optional query-parameters to all requests
|
||||
*
|
||||
* @param additionalQueryParams
|
||||
*/
|
||||
addQueryParams(additionalQueryParams) {
|
||||
this._emsClient.addQueryParams(additionalQueryParams);
|
||||
}
|
||||
|
||||
async getEMSHotLink(fileLayerConfig) {
|
||||
const fileLayers = await this._emsClient.getFileLayers();
|
||||
const layer = fileLayers.find(fileLayer => {
|
||||
const hasIdByName = fileLayer.hasId(fileLayerConfig.name); //legacy
|
||||
const hasIdById = fileLayer.hasId(fileLayerConfig.id);
|
||||
return hasIdByName || hasIdById;
|
||||
});
|
||||
return layer ? layer.getEMSHotLink() : null;
|
||||
}
|
||||
|
||||
async _getAttributesForEMSTMSLayer(isDesaturated, isDarkMode) {
|
||||
const tmsServices = await this._emsClient.getTMSServices();
|
||||
const emsTileLayerId = mapConfig.emsTileLayerId;
|
||||
let serviceId;
|
||||
if (isDarkMode) {
|
||||
serviceId = emsTileLayerId.dark;
|
||||
} else {
|
||||
if (isDesaturated) {
|
||||
serviceId = emsTileLayerId.desaturated;
|
||||
} else {
|
||||
serviceId = emsTileLayerId.bright;
|
||||
}
|
||||
}
|
||||
const tmsService = tmsServices.find(service => {
|
||||
return service.getId() === serviceId;
|
||||
});
|
||||
return {
|
||||
url: await tmsService.getUrlTemplate(),
|
||||
minZoom: await tmsService.getMinZoom(),
|
||||
maxZoom: await tmsService.getMaxZoom(),
|
||||
attribution: await tmsService.getHTMLAttribution(),
|
||||
origin: ORIGIN.EMS,
|
||||
};
|
||||
}
|
||||
|
||||
async getAttributesForTMSLayer(tmsServiceConfig, isDesaturated, isDarkMode) {
|
||||
if (tmsServiceConfig.origin === ORIGIN.EMS) {
|
||||
return this._getAttributesForEMSTMSLayer(isDesaturated, isDarkMode);
|
||||
} else if (tmsServiceConfig.origin === ORIGIN.KIBANA_YML) {
|
||||
const config = tilemapsConfig.deprecated.config;
|
||||
const attrs = _.pick(config, ['url', 'minzoom', 'maxzoom', 'attribution']);
|
||||
return { ...attrs, ...{ origin: ORIGIN.KIBANA_YML } };
|
||||
} else {
|
||||
//this is an older config. need to resolve this dynamically.
|
||||
if (tmsServiceConfig.id === TMS_IN_YML_ID) {
|
||||
const config = tilemapsConfig.deprecated.config;
|
||||
const attrs = _.pick(config, ['url', 'minzoom', 'maxzoom', 'attribution']);
|
||||
return { ...attrs, ...{ origin: ORIGIN.KIBANA_YML } };
|
||||
} else {
|
||||
//assume ems
|
||||
return this._getAttributesForEMSTMSLayer(isDesaturated, isDarkMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async _getFileUrlFromEMS(fileLayerConfig) {
|
||||
const fileLayers = await this._emsClient.getFileLayers();
|
||||
const layer = fileLayers.find(fileLayer => {
|
||||
const hasIdByName = fileLayer.hasId(fileLayerConfig.name); //legacy
|
||||
const hasIdById = fileLayer.hasId(fileLayerConfig.id);
|
||||
return hasIdByName || hasIdById;
|
||||
});
|
||||
|
||||
if (layer) {
|
||||
return layer.getDefaultFormatUrl();
|
||||
} else {
|
||||
throw new Error(`File ${fileLayerConfig.name} not recognized`);
|
||||
}
|
||||
}
|
||||
|
||||
async getUrlForRegionLayer(fileLayerConfig) {
|
||||
let url;
|
||||
if (fileLayerConfig.origin === ORIGIN.EMS) {
|
||||
url = this._getFileUrlFromEMS(fileLayerConfig);
|
||||
} else if (
|
||||
fileLayerConfig.layerId &&
|
||||
fileLayerConfig.layerId.startsWith(`${ORIGIN.EMS}.`)
|
||||
) {
|
||||
//fallback for older saved objects
|
||||
url = this._getFileUrlFromEMS(fileLayerConfig);
|
||||
} else if (
|
||||
fileLayerConfig.layerId &&
|
||||
fileLayerConfig.layerId.startsWith(`${ORIGIN.KIBANA_YML}.`)
|
||||
) {
|
||||
//fallback for older saved objects
|
||||
url = fileLayerConfig.url;
|
||||
} else {
|
||||
//generic fallback
|
||||
url = fileLayerConfig.url;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
async getJsonForRegionLayer(fileLayerConfig) {
|
||||
const url = await this.getUrlForRegionLayer(fileLayerConfig);
|
||||
const response = await fetch(url);
|
||||
return await response.json();
|
||||
}
|
||||
}
|
||||
|
||||
return new ServiceSettings();
|
||||
});
|
6
src/plugins/maps_legacy/kibana.json
Normal file
6
src/plugins/maps_legacy/kibana.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"id": "mapsLegacy",
|
||||
"version": "8.0.0",
|
||||
"kibanaVersion": "kibana",
|
||||
"ui": true
|
||||
}
|
|
@ -26,7 +26,7 @@ import EMS_TILES from './ems_mocks/sample_tiles.json';
|
|||
import EMS_STYLE_ROAD_MAP_BRIGHT from './ems_mocks/sample_style_bright';
|
||||
import EMS_STYLE_ROAD_MAP_DESATURATED from './ems_mocks/sample_style_desaturated';
|
||||
import EMS_STYLE_DARK_MAP from './ems_mocks/sample_style_dark';
|
||||
import { ORIGIN } from '../../../../../core_plugins/tile_map/common/origin';
|
||||
import { ORIGIN } from '../../common/origin';
|
||||
|
||||
describe('service_settings (FKA tilemaptest)', function() {
|
||||
let serviceSettings;
|
|
@ -17,4 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export * from './legacy_dependencies_plugin';
|
||||
export const ORIGIN = {
|
||||
EMS: 'elastic_maps_service',
|
||||
KIBANA_YML: 'self_hosted',
|
||||
};
|
61
src/plugins/maps_legacy/public/index.ts
Normal file
61
src/plugins/maps_legacy/public/index.ts
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { MapsLegacyPlugin } from './plugin';
|
||||
// @ts-ignore
|
||||
import * as colorUtil from './map/color_util';
|
||||
// @ts-ignore
|
||||
import { KibanaMap } from './map/kibana_map';
|
||||
// @ts-ignore
|
||||
import { KibanaMapLayer } from './map/kibana_map_layer';
|
||||
// @ts-ignore
|
||||
import { convertToGeoJson } from './map/convert_to_geojson';
|
||||
// @ts-ignore
|
||||
import { scaleBounds, getPrecision, geoContains } from './map/decode_geo_hash';
|
||||
// @ts-ignore
|
||||
import {
|
||||
VectorLayer,
|
||||
FileLayerField,
|
||||
FileLayer,
|
||||
TmsLayer,
|
||||
IServiceSettings,
|
||||
} from './map/service_settings';
|
||||
|
||||
export function plugin() {
|
||||
return new MapsLegacyPlugin();
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export {
|
||||
scaleBounds,
|
||||
getPrecision,
|
||||
geoContains,
|
||||
colorUtil,
|
||||
convertToGeoJson,
|
||||
IServiceSettings,
|
||||
KibanaMap,
|
||||
KibanaMapLayer,
|
||||
VectorLayer,
|
||||
FileLayerField,
|
||||
FileLayer,
|
||||
TmsLayer,
|
||||
};
|
||||
|
||||
export type MapsLegacyPluginSetup = ReturnType<MapsLegacyPlugin['setup']>;
|
||||
export type MapsLegacyPluginStart = ReturnType<MapsLegacyPlugin['start']>;
|
|
@ -17,7 +17,14 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
// @ts-ignore
|
||||
export { KibanaMapLayer } from 'ui/vis/map/kibana_map_layer';
|
||||
// @ts-ignore
|
||||
export { KibanaMap } from 'ui/vis/map/kibana_map';
|
||||
let toast;
|
||||
export const setToasts = notificationToast => (toast = notificationToast);
|
||||
export const getToasts = () => toast;
|
||||
|
||||
let uiSettings;
|
||||
export const setUiSettings = coreUiSettings => (uiSettings = coreUiSettings);
|
||||
export const getUiSettings = () => uiSettings;
|
||||
|
||||
let getInjectedVar;
|
||||
export const setInjectedVarFunc = getInjectedVarFunc => (getInjectedVar = getInjectedVarFunc);
|
||||
export const getInjectedVarFunc = () => getInjectedVar;
|
|
@ -17,11 +17,8 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
import _ from 'lodash';
|
||||
|
||||
const config = chrome.getUiSettingsClient();
|
||||
|
||||
interface DecodedGeoHash {
|
||||
latitude: number[];
|
||||
longitude: number[];
|
||||
|
@ -74,6 +71,10 @@ function refineInterval(interval: number[], cd: number, mask: number) {
|
|||
}
|
||||
}
|
||||
|
||||
export function geohashColumns(precision: number): number {
|
||||
return geohashCells(precision, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of geohash cells for a given precision
|
||||
*
|
||||
|
@ -90,51 +91,6 @@ function geohashCells(precision: number, axis: number) {
|
|||
return cells;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of geohash columns (world-wide) for a given precision
|
||||
* @param precision the geohash precision
|
||||
* @returns {number} the number of columns
|
||||
*/
|
||||
export function geohashColumns(precision: number): number {
|
||||
return geohashCells(precision, 0);
|
||||
}
|
||||
|
||||
const defaultPrecision = 2;
|
||||
const maxPrecision = parseInt(config.get('visualization:tileMap:maxPrecision'), 10) || 12;
|
||||
/**
|
||||
* Map Leaflet zoom levels to geohash precision levels.
|
||||
* The size of a geohash column-width on the map should be at least `minGeohashPixels` pixels wide.
|
||||
*/
|
||||
export const zoomPrecision: any = {};
|
||||
const minGeohashPixels = 16;
|
||||
|
||||
for (let zoom = 0; zoom <= 21; zoom += 1) {
|
||||
const worldPixels = 256 * Math.pow(2, zoom);
|
||||
zoomPrecision[zoom] = 1;
|
||||
for (let precision = 2; precision <= maxPrecision; precision += 1) {
|
||||
const columns = geohashColumns(precision);
|
||||
if (worldPixels / columns >= minGeohashPixels) {
|
||||
zoomPrecision[zoom] = precision;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getPrecision(val: string) {
|
||||
let precision = parseInt(val, 10);
|
||||
|
||||
if (Number.isNaN(precision)) {
|
||||
precision = defaultPrecision;
|
||||
}
|
||||
|
||||
if (precision > maxPrecision) {
|
||||
return maxPrecision;
|
||||
}
|
||||
|
||||
return precision;
|
||||
}
|
||||
|
||||
interface GeoBoundingBoxCoordinate {
|
||||
lat: number;
|
||||
lon: number;
|
|
@ -24,7 +24,7 @@ import $ from 'jquery';
|
|||
import _ from 'lodash';
|
||||
import { zoomToPrecision } from './zoom_to_precision';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ORIGIN } from '../../../../core_plugins/tile_map/common/origin';
|
||||
import { ORIGIN } from '../common/origin';
|
||||
|
||||
function makeFitControl(fitContainer, kibanaMap) {
|
||||
const FitControl = L.Control.extend({
|
||||
|
@ -39,7 +39,7 @@ function makeFitControl(fitContainer, kibanaMap) {
|
|||
onAdd: function(leafletMap) {
|
||||
this._leafletMap = leafletMap;
|
||||
const fitDatBoundsLabel = i18n.translate(
|
||||
'common.ui.vis.kibanaMap.leaflet.fitDataBoundsAriaLabel',
|
||||
'maps_legacy.kibanaMap.leaflet.fitDataBoundsAriaLabel',
|
||||
{ defaultMessage: 'Fit Data Bounds' }
|
||||
);
|
||||
$(this._fitContainer)
|
||||
|
@ -101,7 +101,7 @@ function makeLegendControl(container, kibanaMap, position) {
|
|||
* Serves as simple abstraction for leaflet as well.
|
||||
*/
|
||||
export class KibanaMap extends EventEmitter {
|
||||
constructor(containerNode, options) {
|
||||
constructor(containerNode, options, services) {
|
||||
super();
|
||||
this._containerNode = containerNode;
|
||||
this._leafletBaseLayer = null;
|
||||
|
@ -116,6 +116,7 @@ export class KibanaMap extends EventEmitter {
|
|||
this._layers = [];
|
||||
this._listeners = [];
|
||||
this._showTooltip = false;
|
||||
this.toastService = services ? services.toastService : null;
|
||||
|
||||
const leafletOptions = {
|
||||
minZoom: options.minZoom,
|
||||
|
@ -482,15 +483,21 @@ export class KibanaMap extends EventEmitter {
|
|||
}
|
||||
|
||||
_addMaxZoomMessage = layer => {
|
||||
const zoomWarningMsg = createZoomWarningMsg(this.getZoomLevel, this.getMaxZoomLevel);
|
||||
if (this.toastService) {
|
||||
const zoomWarningMsg = createZoomWarningMsg(
|
||||
this.toastService,
|
||||
this.getZoomLevel,
|
||||
this.getMaxZoomLevel
|
||||
);
|
||||
|
||||
this._leafletMap.on('zoomend', zoomWarningMsg);
|
||||
this._containerNode.setAttribute('data-test-subj', 'zoomWarningEnabled');
|
||||
this._leafletMap.on('zoomend', zoomWarningMsg);
|
||||
this._containerNode.setAttribute('data-test-subj', 'zoomWarningEnabled');
|
||||
|
||||
layer.on('remove', () => {
|
||||
this._leafletMap.off('zoomend', zoomWarningMsg);
|
||||
this._containerNode.removeAttribute('data-test-subj');
|
||||
});
|
||||
layer.on('remove', () => {
|
||||
this._leafletMap.off('zoomend', zoomWarningMsg);
|
||||
this._containerNode.removeAttribute('data-test-subj');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
setLegendPosition(position) {
|
|
@ -17,11 +17,10 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { toastNotifications } from 'ui/notify';
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { EuiSpacer, EuiButtonEmpty } from '@elastic/eui';
|
||||
import { toMountPoint } from '../../../../../plugins/kibana_react/public';
|
||||
import { toMountPoint } from '../../../kibana_react/public';
|
||||
|
||||
export const createZoomWarningMsg = (function() {
|
||||
let disableZoomMsg = false;
|
||||
|
@ -40,7 +39,7 @@ export const createZoomWarningMsg = (function() {
|
|||
<div>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="common.ui.vis.kibanaMap.zoomWarning"
|
||||
id="maps_legacy.kibanaMap.zoomWarning"
|
||||
defaultMessage="You've reached the maximum number of zoom
|
||||
levels. To zoom all the way in, upgrade to the
|
||||
{defaultDistribution} of Elasticsearch and Kibana. You'll get
|
||||
|
@ -105,12 +104,12 @@ export const createZoomWarningMsg = (function() {
|
|||
'data-test-subj': 'maxZoomWarning',
|
||||
};
|
||||
|
||||
return (getZoomLevel, getMaxZoomLevel) => {
|
||||
return (toastService, getZoomLevel, getMaxZoomLevel) => {
|
||||
return () => {
|
||||
const zoomLevel = getZoomLevel();
|
||||
const maxMapZoom = getMaxZoomLevel();
|
||||
if (!disableZoomMsg && zoomLevel === maxMapZoom) {
|
||||
toastNotifications.addDanger(zoomToast);
|
||||
toastService.addDanger(zoomToast);
|
||||
}
|
||||
};
|
||||
};
|
74
src/plugins/maps_legacy/public/map/precision.ts
Normal file
74
src/plugins/maps_legacy/public/map/precision.ts
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
// @ts-ignore
|
||||
import { getUiSettings } from '../kibana_services';
|
||||
import { geohashColumns } from './decode_geo_hash';
|
||||
|
||||
/**
|
||||
* Get the number of geohash columns (world-wide) for a given precision
|
||||
* @param precision the geohash precision
|
||||
* @returns {number} the number of columns
|
||||
*/
|
||||
|
||||
const DEFAULT_PRECISION = 2;
|
||||
|
||||
function getMaxPrecision() {
|
||||
const config = getUiSettings();
|
||||
return parseInt(config.get('visualization:tileMap:maxPrecision'), 10) || 12;
|
||||
}
|
||||
|
||||
export function getZoomPrecision() {
|
||||
/**
|
||||
* Map Leaflet zoom levels to geohash precision levels.
|
||||
* The size of a geohash column-width on the map should be at least `minGeohashPixels` pixels wide.
|
||||
*/
|
||||
const zoomPrecision: any = {};
|
||||
const minGeohashPixels = 16;
|
||||
const maxPrecision = getMaxPrecision();
|
||||
|
||||
for (let zoom = 0; zoom <= 21; zoom += 1) {
|
||||
const worldPixels = 256 * Math.pow(2, zoom);
|
||||
zoomPrecision[zoom] = 1;
|
||||
for (let precision = 2; precision <= maxPrecision; precision += 1) {
|
||||
const columns = geohashColumns(precision);
|
||||
if (worldPixels / columns >= minGeohashPixels) {
|
||||
zoomPrecision[zoom] = precision;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return zoomPrecision;
|
||||
}
|
||||
|
||||
export function getPrecision(val: string) {
|
||||
let precision = parseInt(val, 10);
|
||||
const maxPrecision = getMaxPrecision();
|
||||
|
||||
if (Number.isNaN(precision)) {
|
||||
precision = DEFAULT_PRECISION;
|
||||
}
|
||||
|
||||
if (precision > maxPrecision) {
|
||||
return maxPrecision;
|
||||
}
|
||||
|
||||
return precision;
|
||||
}
|
|
@ -44,7 +44,7 @@ export interface VectorLayer extends FileLayer {
|
|||
isEMS: boolean;
|
||||
}
|
||||
|
||||
export interface ServiceSettings {
|
||||
export interface IServiceSettings {
|
||||
getEMSHotLink(layer: FileLayer): Promise<string>;
|
||||
getTMSServices(): Promise<TmsLayer[]>;
|
||||
getFileLayers(): Promise<FileLayer[]>;
|
254
src/plugins/maps_legacy/public/map/service_settings.js
Normal file
254
src/plugins/maps_legacy/public/map/service_settings.js
Normal file
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import _ from 'lodash';
|
||||
import MarkdownIt from 'markdown-it';
|
||||
import { EMSClient } from '@elastic/ems-client';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { getInjectedVarFunc } from '../kibana_services';
|
||||
import { ORIGIN } from '../common/origin';
|
||||
|
||||
const TMS_IN_YML_ID = 'TMS in config/kibana.yml';
|
||||
|
||||
export class ServiceSettings {
|
||||
constructor() {
|
||||
const getInjectedVar = getInjectedVarFunc();
|
||||
this.mapConfig = getInjectedVar('mapConfig');
|
||||
this.tilemapsConfig = getInjectedVar('tilemapsConfig');
|
||||
const kbnVersion = getInjectedVar('version');
|
||||
|
||||
this._showZoomMessage = true;
|
||||
this._emsClient = new EMSClient({
|
||||
language: i18n.getLocale(),
|
||||
appVersion: kbnVersion,
|
||||
appName: 'kibana',
|
||||
fileApiUrl: this.mapConfig.emsFileApiUrl,
|
||||
tileApiUrl: this.mapConfig.emsTileApiUrl,
|
||||
landingPageUrl: this.mapConfig.emsLandingPageUrl,
|
||||
// Wrap to avoid errors passing window fetch
|
||||
fetchFunction: function(...args) {
|
||||
return fetch(...args);
|
||||
},
|
||||
});
|
||||
this.getTMSOptions();
|
||||
}
|
||||
|
||||
getTMSOptions() {
|
||||
const markdownIt = new MarkdownIt({
|
||||
html: false,
|
||||
linkify: true,
|
||||
});
|
||||
|
||||
// TMS attribution
|
||||
const attributionFromConfig = _.escape(
|
||||
markdownIt.render(this.tilemapsConfig.deprecated.config.options.attribution || '')
|
||||
);
|
||||
// TMS Options
|
||||
this.tmsOptionsFromConfig = _.assign({}, this.tilemapsConfig.deprecated.config.options, {
|
||||
attribution: attributionFromConfig,
|
||||
});
|
||||
}
|
||||
|
||||
shouldShowZoomMessage({ origin }) {
|
||||
return origin === ORIGIN.EMS && this._showZoomMessage;
|
||||
}
|
||||
|
||||
disableZoomMessage() {
|
||||
this._showZoomMessage = false;
|
||||
}
|
||||
|
||||
__debugStubManifestCalls(manifestRetrieval) {
|
||||
const oldGetManifest = this._emsClient.getManifest;
|
||||
this._emsClient.getManifest = manifestRetrieval;
|
||||
return {
|
||||
removeStub: () => {
|
||||
delete this._emsClient.getManifest;
|
||||
//not strictly necessary since this is prototype method
|
||||
if (this._emsClient.getManifest !== oldGetManifest) {
|
||||
this._emsClient.getManifest = oldGetManifest;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async getFileLayers() {
|
||||
if (!this.mapConfig.includeElasticMapsService) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const fileLayers = await this._emsClient.getFileLayers();
|
||||
return fileLayers.map(fileLayer => {
|
||||
//backfill to older settings
|
||||
const format = fileLayer.getDefaultFormatType();
|
||||
const meta = fileLayer.getDefaultFormatMeta();
|
||||
|
||||
return {
|
||||
name: fileLayer.getDisplayName(),
|
||||
origin: fileLayer.getOrigin(),
|
||||
id: fileLayer.getId(),
|
||||
created_at: fileLayer.getCreatedAt(),
|
||||
attribution: fileLayer.getHTMLAttribution(),
|
||||
fields: fileLayer.getFieldsInLanguage(),
|
||||
format: format, //legacy: format and meta are split up
|
||||
meta: meta, //legacy, format and meta are split up
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the services published by EMS (if configures)
|
||||
* It also includes the service configured in tilemap (override)
|
||||
*/
|
||||
async getTMSServices() {
|
||||
let allServices = [];
|
||||
if (this.tilemapsConfig.deprecated.isOverridden) {
|
||||
//use tilemap.* settings from yml
|
||||
const tmsService = _.cloneDeep(this.tmsOptionsFromConfig);
|
||||
tmsService.id = TMS_IN_YML_ID;
|
||||
tmsService.origin = ORIGIN.KIBANA_YML;
|
||||
allServices.push(tmsService);
|
||||
}
|
||||
|
||||
if (this.mapConfig.includeElasticMapsService) {
|
||||
const servicesFromManifest = await this._emsClient.getTMSServices();
|
||||
const strippedServiceFromManifest = await Promise.all(
|
||||
servicesFromManifest
|
||||
.filter(tmsService => tmsService.getId() === this.mapConfig.emsTileLayerId.bright)
|
||||
.map(async tmsService => {
|
||||
//shim for compatibility
|
||||
return {
|
||||
origin: tmsService.getOrigin(),
|
||||
id: tmsService.getId(),
|
||||
minZoom: await tmsService.getMinZoom(),
|
||||
maxZoom: await tmsService.getMaxZoom(),
|
||||
attribution: tmsService.getHTMLAttribution(),
|
||||
};
|
||||
})
|
||||
);
|
||||
allServices = allServices.concat(strippedServiceFromManifest);
|
||||
}
|
||||
|
||||
return allServices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add optional query-parameters to all requests
|
||||
*
|
||||
* @param additionalQueryParams
|
||||
*/
|
||||
addQueryParams(additionalQueryParams) {
|
||||
this._emsClient.addQueryParams(additionalQueryParams);
|
||||
}
|
||||
|
||||
async getEMSHotLink(fileLayerConfig) {
|
||||
const fileLayers = await this._emsClient.getFileLayers();
|
||||
const layer = fileLayers.find(fileLayer => {
|
||||
const hasIdByName = fileLayer.hasId(fileLayerConfig.name); //legacy
|
||||
const hasIdById = fileLayer.hasId(fileLayerConfig.id);
|
||||
return hasIdByName || hasIdById;
|
||||
});
|
||||
return layer ? layer.getEMSHotLink() : null;
|
||||
}
|
||||
|
||||
async _getAttributesForEMSTMSLayer(isDesaturated, isDarkMode) {
|
||||
const tmsServices = await this._emsClient.getTMSServices();
|
||||
const emsTileLayerId = this.mapConfig.emsTileLayerId;
|
||||
let serviceId;
|
||||
if (isDarkMode) {
|
||||
serviceId = emsTileLayerId.dark;
|
||||
} else {
|
||||
if (isDesaturated) {
|
||||
serviceId = emsTileLayerId.desaturated;
|
||||
} else {
|
||||
serviceId = emsTileLayerId.bright;
|
||||
}
|
||||
}
|
||||
const tmsService = tmsServices.find(service => {
|
||||
return service.getId() === serviceId;
|
||||
});
|
||||
return {
|
||||
url: await tmsService.getUrlTemplate(),
|
||||
minZoom: await tmsService.getMinZoom(),
|
||||
maxZoom: await tmsService.getMaxZoom(),
|
||||
attribution: await tmsService.getHTMLAttribution(),
|
||||
origin: ORIGIN.EMS,
|
||||
};
|
||||
}
|
||||
|
||||
async getAttributesForTMSLayer(tmsServiceConfig, isDesaturated, isDarkMode) {
|
||||
if (tmsServiceConfig.origin === ORIGIN.EMS) {
|
||||
return this._getAttributesForEMSTMSLayer(isDesaturated, isDarkMode);
|
||||
} else if (tmsServiceConfig.origin === ORIGIN.KIBANA_YML) {
|
||||
const config = this.tilemapsConfig.deprecated.config;
|
||||
const attrs = _.pick(config, ['url', 'minzoom', 'maxzoom', 'attribution']);
|
||||
return { ...attrs, ...{ origin: ORIGIN.KIBANA_YML } };
|
||||
} else {
|
||||
//this is an older config. need to resolve this dynamically.
|
||||
if (tmsServiceConfig.id === TMS_IN_YML_ID) {
|
||||
const config = this.tilemapsConfig.deprecated.config;
|
||||
const attrs = _.pick(config, ['url', 'minzoom', 'maxzoom', 'attribution']);
|
||||
return { ...attrs, ...{ origin: ORIGIN.KIBANA_YML } };
|
||||
} else {
|
||||
//assume ems
|
||||
return this._getAttributesForEMSTMSLayer(isDesaturated, isDarkMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async _getFileUrlFromEMS(fileLayerConfig) {
|
||||
const fileLayers = await this._emsClient.getFileLayers();
|
||||
const layer = fileLayers.find(fileLayer => {
|
||||
const hasIdByName = fileLayer.hasId(fileLayerConfig.name); //legacy
|
||||
const hasIdById = fileLayer.hasId(fileLayerConfig.id);
|
||||
return hasIdByName || hasIdById;
|
||||
});
|
||||
|
||||
if (layer) {
|
||||
return layer.getDefaultFormatUrl();
|
||||
} else {
|
||||
throw new Error(`File ${fileLayerConfig.name} not recognized`);
|
||||
}
|
||||
}
|
||||
|
||||
async getUrlForRegionLayer(fileLayerConfig) {
|
||||
let url;
|
||||
if (fileLayerConfig.origin === ORIGIN.EMS) {
|
||||
url = this._getFileUrlFromEMS(fileLayerConfig);
|
||||
} else if (fileLayerConfig.layerId && fileLayerConfig.layerId.startsWith(`${ORIGIN.EMS}.`)) {
|
||||
//fallback for older saved objects
|
||||
url = this._getFileUrlFromEMS(fileLayerConfig);
|
||||
} else if (
|
||||
fileLayerConfig.layerId &&
|
||||
fileLayerConfig.layerId.startsWith(`${ORIGIN.KIBANA_YML}.`)
|
||||
) {
|
||||
//fallback for older saved objects
|
||||
url = fileLayerConfig.url;
|
||||
} else {
|
||||
//generic fallback
|
||||
url = fileLayerConfig.url;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
async getJsonForRegionLayer(fileLayerConfig) {
|
||||
const url = await this.getUrlForRegionLayer(fileLayerConfig);
|
||||
const response = await fetch(url);
|
||||
return await response.json();
|
||||
}
|
||||
}
|
57
src/plugins/maps_legacy/public/plugin.ts
Normal file
57
src/plugins/maps_legacy/public/plugin.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
// @ts-ignore
|
||||
import { CoreSetup, CoreStart, Plugin } from 'kibana/public';
|
||||
// @ts-ignore
|
||||
import { setToasts, setUiSettings, setInjectedVarFunc } from './kibana_services';
|
||||
// @ts-ignore
|
||||
import { ServiceSettings } from './map/service_settings';
|
||||
// @ts-ignore
|
||||
import { getPrecision, getZoomPrecision } from './map/precision';
|
||||
import { MapsLegacyPluginSetup, MapsLegacyPluginStart } from './index';
|
||||
|
||||
/**
|
||||
* These are the interfaces with your public contracts. You should export these
|
||||
* for other plugins to use in _their_ `SetupDeps`/`StartDeps` interfaces.
|
||||
* @public
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface MapsLegacySetupDependencies {}
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface MapsLegacyStartDependencies {}
|
||||
|
||||
export class MapsLegacyPlugin implements Plugin<MapsLegacyPluginSetup, MapsLegacyPluginStart> {
|
||||
constructor() {}
|
||||
|
||||
public setup(core: CoreSetup, plugins: MapsLegacySetupDependencies) {
|
||||
setToasts(core.notifications.toasts);
|
||||
setUiSettings(core.uiSettings);
|
||||
setInjectedVarFunc(core.injectedMetadata.getInjectedVar);
|
||||
|
||||
return {
|
||||
serviceSettings: new ServiceSettings(),
|
||||
getZoomPrecision,
|
||||
getPrecision,
|
||||
};
|
||||
}
|
||||
|
||||
public start(core: CoreStart, plugins: MapsLegacyStartDependencies) {}
|
||||
}
|
|
@ -4,20 +4,13 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import uiRoutes from 'ui/routes';
|
||||
import { xpackInfo } from 'plugins/xpack_main/services/xpack_info';
|
||||
import 'ui/vis/map/service_settings';
|
||||
import { npSetup } from 'ui/new_platform';
|
||||
|
||||
uiRoutes.addSetupWork(function($injector, serviceSettings) {
|
||||
const tileMapPluginInfo = xpackInfo.get('features.tilemap');
|
||||
const tileMapPluginInfo = xpackInfo.get('features.tilemap');
|
||||
|
||||
if (!tileMapPluginInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tileMapPluginInfo.license.active || !tileMapPluginInfo.license.valid) {
|
||||
return;
|
||||
}
|
||||
if (tileMapPluginInfo && (tileMapPluginInfo.license.active || tileMapPluginInfo.license.valid)) {
|
||||
const { serviceSettings } = npSetup.plugins.mapsLegacy;
|
||||
serviceSettings.addQueryParams({ license: tileMapPluginInfo.license.uid });
|
||||
serviceSettings.disableZoomMessage();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -319,8 +319,6 @@
|
|||
"common.ui.stateManagement.unableToStoreHistoryInSessionErrorMessage": "セッションがいっぱいで安全に削除できるアイテムが見つからないため、Kibana は履歴アイテムを保存できません。\n\nこれは大抵新規タブに移動することで解決されますが、より大きな問題が原因である可能性もあります。このメッセージが定期的に表示される場合は、{gitHubIssuesUrl} で問題を報告してください。",
|
||||
"common.ui.url.replacementFailedErrorMessage": "置換に失敗、未解決の表現式: {expr}",
|
||||
"common.ui.url.savedObjectIsMissingNotificationMessage": "保存されたオブジェクトがありません",
|
||||
"common.ui.vis.kibanaMap.leaflet.fitDataBoundsAriaLabel": "データバウンドを合わせる",
|
||||
"common.ui.vis.kibanaMap.zoomWarning": "ズームレベルが最大に達しました。完全にズームインするには、Elasticsearch と Kibana の {defaultDistribution} にアップグレードしてください。{ems} でより多くのズームレベルが利用できます。または、独自のマップサーバーを構成できます。詳細は { wms } または { configSettings} をご覧ください。",
|
||||
"console.autocomplete.addMethodMetaText": "メソド",
|
||||
"console.consoleDisplayName": "コンソール",
|
||||
"console.consoleMenu.copyAsCurlMessage": "リクエストが URL としてコピーされました",
|
||||
|
|
|
@ -319,8 +319,6 @@
|
|||
"common.ui.stateManagement.unableToStoreHistoryInSessionErrorMessage": "Kibana 无法将历史记录项存储在您的会话中,因为其已满,并且似乎没有任何可安全删除的项。\n\n通常可通过移至新的标签页来解决此问题,但这会导致更大的问题。如果您有规律地看到此消息,请在 {gitHubIssuesUrl} 提交问题。",
|
||||
"common.ui.url.replacementFailedErrorMessage": "替换失败,未解析的表达式:{expr}",
|
||||
"common.ui.url.savedObjectIsMissingNotificationMessage": "已保存对象缺失",
|
||||
"common.ui.vis.kibanaMap.leaflet.fitDataBoundsAriaLabel": "适应数据边界",
|
||||
"common.ui.vis.kibanaMap.zoomWarning": "已达到缩放级别最大数目。要一直放大,请升级到 Elasticsearch 和 Kibana 的 {defaultDistribution}。您可以通过 {ems} 免费使用其他缩放级别。或者,您可以配置自己的地图服务器。请前往 { wms } 或 { configSettings} 以获取详细信息。",
|
||||
"console.autocomplete.addMethodMetaText": "方法",
|
||||
"console.consoleDisplayName": "控制台",
|
||||
"console.consoleMenu.copyAsCurlMessage": "请求已复制为 cURL",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue