[Maps] deprecate 'map.regionmap' kibana config and 'Configured GeoJSON' source (#103373)

* [Maps] deprecate 'map.regionmap' kibana config and 'Configured GeoJSON' source

* clean up message

* revert change to KibanaRegionmapSource.getGeoJsonWithMeta

* tslint

* doc updates

* clean up

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Nathan Reese 2021-06-28 16:27:41 -06:00 committed by GitHub
parent 196531502f
commit bf6be219e8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 144 additions and 189 deletions

View file

@ -34,7 +34,6 @@ To disable EMS, change your <<settings, kibana.yml>> file.
. Set `map.includeElasticMapsService` to `false` to turn off the EMS connection.
. Set `map.tilemap.url` to the URL of your tile server. This configures the default tile layer of Maps.
. (Optional) Set `map.regionmap` to the vector shapes of the administrative boundaries that you want to use.
[float]
[id=elastic-maps-server]

View file

@ -368,8 +368,7 @@ The time interval policy will rotate the log file every given interval of time.
| [[regionmap-ES-map]] `map.includeElasticMapsService:` {ess-icon}
| Set to `false` to disable connections to Elastic Maps Service.
When `includeElasticMapsService` is turned off, only the vector layers configured by <<regionmap-settings, `map.regionmap`>>
and the tile layer configured by <<tilemap-url, `map.tilemap.url`>> are available in <<maps, Maps>>. *Default: `true`*
When `includeElasticMapsService` is turned off, only tile layer configured by <<tilemap-url, `map.tilemap.url`>> is available in <<maps, Maps>>. *Default: `true`*
| `map.emsUrl:`
| Specifies the URL of a self hosted <<elastic-maps-server,{hosted-ems}>>
@ -379,7 +378,8 @@ and the tile layer configured by <<tilemap-url, `map.tilemap.url`>> are availabl
requests through the {kib} server. *Default: `false`*
| [[regionmap-settings]] `map.regionmap:` {ess-icon}
| Specifies additional vector layers for
| deprecated:[7.14.0,"In 8.0 and later, this setting will no longer be supported."]
Specifies additional vector layers for
use in <<maps, Maps>> visualizations. Each layer
object points to an external vector file that contains a geojson
FeatureCollection. The file must use the
@ -393,7 +393,6 @@ The following example shows a valid region map configuration.
[source,text]
--
map.regionmap:
includeElasticMapsService: false
layers:
- name: "Departments of France"
url: "http://my.cors.enabled.server.org/france_departements.geojson"
@ -409,10 +408,12 @@ map.regionmap:
|===
| [[regionmap-attribution]] `map.regionmap.layers[].attribution:` {ess-icon}
| Optional. References the originating source of the geojson file.
| deprecated:[7.14.0,"In 8.0 and later, this setting will no longer be supported."]
Optional. References the originating source of the geojson file.
| [[regionmap-fields]] `map.regionmap.layers[].fields[]:` {ess-icon}
| Mandatory. Each layer
| deprecated:[7.14.0,"In 8.0 and later, this setting will no longer be supported."]
Mandatory. Each layer
can contain multiple fields to indicate what properties from the geojson
features you wish to expose. The following shows how to define multiple
properties:
@ -422,7 +423,6 @@ properties:
[source,text]
--
map.regionmap:
includeElasticMapsService: false
layers:
- name: "Departments of France"
url: "http://my.cors.enabled.server.org/france_departements.geojson"
@ -438,11 +438,13 @@ map.regionmap:
|===
| [[regionmap-field-description]] `map.regionmap.layers[].fields[].description:` {ess-icon}
| Mandatory. The human readable text that is shown under the Options tab when
| deprecated:[7.14.0,"In 8.0 and later, this setting will no longer be supported."]
Mandatory. The human readable text that is shown under the Options tab when
building the Region Map visualization.
| [[regionmap-field-name]] `map.regionmap.layers[].fields[].name:` {ess-icon}
| Mandatory.
| deprecated:[7.14.0,"In 8.0 and later, this setting will no longer be supported."]
Mandatory.
This value is used to do an inner-join between the document stored in
{es} and the geojson file. For example, if the field in the geojson is
called `Location` and has city names, there must be a field in {es}
@ -450,12 +452,12 @@ that holds the same values that {kib} can then use to lookup for the geoshape
data.
| [[regionmap-name]] `map.regionmap.layers[].name:` {ess-icon}
| Mandatory. A description of
the map being provided.
| deprecated:[7.14.0,"In 8.0 and later, this setting will no longer be supported."]
Mandatory. A description of the map being provided.
| [[regionmap-url]] `map.regionmap.layers[].url:` {ess-icon}
| Mandatory. The location of the
geojson file as provided by a webserver.
| deprecated:[7.14.0,"In 8.0 and later, this setting will no longer be supported."]
Mandatory. The location of the geojson file as provided by a webserver.
| [[tilemap-settings]] `map.tilemap.options.attribution:` {ess-icon}
| The map attribution string.

View file

@ -265,11 +265,6 @@ export enum SCALING_TYPES {
MVT = 'MVT',
}
export enum FORMAT_TYPE {
GEOJSON = 'geojson',
TOPOJSON = 'topojson',
}
export enum MVT_FIELD_TYPE {
STRING = 'String',
NUMBER = 'Number',

View file

@ -20,8 +20,6 @@ import { emsBoundariesLayerWizardConfig } from '../sources/ems_file_source';
// @ts-ignore
import { emsBaseMapLayerWizardConfig } from '../sources/ems_tms_source';
// @ts-ignore
import { kibanaRegionMapLayerWizardConfig } from '../sources/kibana_regionmap_source';
// @ts-ignore
import { kibanaBasemapLayerWizardConfig } from '../sources/kibana_tilemap_source';
import { tmsLayerWizardConfig } from '../sources/xyz_tms_source';
// @ts-ignore
@ -59,8 +57,6 @@ export function registerLayerWizards() {
// @ts-ignore
registerLayerWizard(emsBaseMapLayerWizardConfig);
// @ts-ignore
registerLayerWizard(kibanaRegionMapLayerWizardConfig);
// @ts-ignore
registerLayerWizard(kibanaBasemapLayerWizardConfig);
registerLayerWizard(tmsLayerWizardConfig);
// @ts-ignore

View file

@ -236,11 +236,17 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer {
}
const sourceDataRequest = this.getSourceDataRequest();
const { tooltipContent, areResultsTrimmed } = this.getSource().getSourceTooltipContent(
sourceDataRequest
);
const {
tooltipContent,
areResultsTrimmed,
isDeprecated,
} = this.getSource().getSourceTooltipContent(sourceDataRequest);
return {
icon: this.getCurrentStyle().getIcon(),
icon: isDeprecated ? (
<EuiIcon type="alert" color="danger" />
) : (
this.getCurrentStyle().getIcon()
),
tooltipContent,
areResultsTrimmed,
};

View file

@ -1,55 +0,0 @@
/*
* 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 PropTypes from 'prop-types';
import { EuiSelect, EuiFormRow, EuiPanel } from '@elastic/eui';
import { getKibanaRegionList } from '../../../util';
import { i18n } from '@kbn/i18n';
export function CreateSourceEditor({ onSourceConfigChange }) {
const onChange = ({ target }) => {
const selectedName = target.options[target.selectedIndex].text;
onSourceConfigChange({ name: selectedName });
};
const regionmapOptions = getKibanaRegionList().map(({ name, url }) => {
return {
value: url,
text: name,
};
});
const helpText =
regionmapOptions.length === 0
? i18n.translate('xpack.maps.source.kbnRegionMap.noLayerAvailableHelptext', {
defaultMessage: `No vector layers are available. Ask your system administrator to set "map.regionmap" in kibana.yml.`,
})
: null;
return (
<EuiPanel>
<EuiFormRow
label={i18n.translate('xpack.maps.source.kbnRegionMap.vectorLayerLabel', {
defaultMessage: 'Vector layer',
})}
helpText={helpText}
>
<EuiSelect
hasNoInitialSelection
options={regionmapOptions}
onChange={onChange}
disabled={regionmapOptions.length === 0}
/>
</EuiFormRow>
</EuiPanel>
);
}
CreateSourceEditor.propTypes = {
onSourceConfigChange: PropTypes.func.isRequired,
};

View file

@ -0,0 +1,56 @@
/*
* 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 _ from 'lodash';
import { i18n } from '@kbn/i18n';
import { FeatureCollection } from 'geojson';
import * as topojson from 'topojson-client';
import { GeometryCollection } from 'topojson-specification';
import fetch from 'node-fetch';
export enum FORMAT_TYPE {
GEOJSON = 'geojson',
TOPOJSON = 'topojson',
}
export async function fetchGeoJson(
fetchUrl: string,
format: FORMAT_TYPE,
featureCollectionPath: string
): Promise<FeatureCollection> {
let fetchedJson;
try {
const response = await fetch(fetchUrl);
if (!response.ok) {
throw new Error('Request failed');
}
fetchedJson = await response.json();
} catch (e) {
throw new Error(
i18n.translate('xpack.maps.util.requestFailedErrorMessage', {
defaultMessage: `Unable to fetch vector shapes from url: {fetchUrl}`,
values: { fetchUrl },
})
);
}
if (format === FORMAT_TYPE.GEOJSON) {
return fetchedJson;
}
if (format === FORMAT_TYPE.TOPOJSON) {
const features = _.get(fetchedJson, `objects.${featureCollectionPath}`) as GeometryCollection;
return topojson.feature(fetchedJson, features);
}
throw new Error(
i18n.translate('xpack.maps.util.formatErrorMessage', {
defaultMessage: `Unable to fetch vector shapes from url: {format}`,
values: { format },
})
);
}

View file

@ -5,5 +5,4 @@
* 2.0.
*/
export { kibanaRegionMapLayerWizardConfig } from './kibana_regionmap_layer_wizard';
export { KibanaRegionmapSource } from './kibana_regionmap_source';

View file

@ -1,39 +0,0 @@
/*
* 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 { i18n } from '@kbn/i18n';
import { LayerWizard, RenderWizardArguments } from '../../layers/layer_wizard_registry';
// @ts-ignore
import { KibanaRegionmapSource, sourceTitle } from './kibana_regionmap_source';
import { VectorLayer } from '../../layers/vector_layer';
// @ts-ignore
import { CreateSourceEditor } from './create_source_editor';
import { getKibanaRegionList } from '../../../util';
import { LAYER_WIZARD_CATEGORY } from '../../../../common/constants';
export const kibanaRegionMapLayerWizardConfig: LayerWizard = {
categories: [LAYER_WIZARD_CATEGORY.REFERENCE],
checkVisibility: async () => {
const regions = getKibanaRegionList();
return regions.length > 0;
},
description: i18n.translate('xpack.maps.source.kbnRegionMapDescription', {
defaultMessage: 'Vector data from hosted GeoJSON configured in kibana.yml',
}),
icon: 'logoKibana',
renderWizard: ({ previewLayers, mapColors }: RenderWizardArguments) => {
const onSourceConfigChange = (sourceConfig: { name: string }) => {
const sourceDescriptor = KibanaRegionmapSource.createDescriptor(sourceConfig);
const layerDescriptor = VectorLayer.createDescriptor({ sourceDescriptor }, mapColors);
previewLayers([layerDescriptor]);
};
return <CreateSourceEditor onSourceConfigChange={onSourceConfigChange} />;
},
title: sourceTitle,
};

View file

@ -7,17 +7,18 @@
import { i18n } from '@kbn/i18n';
import { AbstractVectorSource, GeoJsonWithMeta } from '../vector_source';
import { fetchGeoJson, getKibanaRegionList } from '../../../util';
import { getRegionmapLayers } from '../../../kibana_services';
import { getDataSourceLabel } from '../../../../common/i18n_getters';
import { FIELD_ORIGIN, FORMAT_TYPE, SOURCE_TYPES } from '../../../../common/constants';
import { FIELD_ORIGIN, SOURCE_TYPES } from '../../../../common/constants';
import { KibanaRegionField } from '../../fields/kibana_region_field';
import { registerSource } from '../source_registry';
import { KibanaRegionmapSourceDescriptor } from '../../../../common/descriptor_types';
import { Adapters } from '../../../../../../../src/plugins/inspector/common/adapters';
import { IField } from '../../fields/field';
import type { LayerConfig } from '../../../../../../../src/plugins/maps_ems/public';
import { fetchGeoJson, FORMAT_TYPE } from './fetch_geojson';
export const sourceTitle = i18n.translate('xpack.maps.source.kbnRegionMapTitle', {
const sourceTitle = i18n.translate('xpack.maps.source.kbnRegionMapTitle', {
defaultMessage: 'Configured GeoJSON',
});
@ -45,6 +46,7 @@ export class KibanaRegionmapSource extends AbstractVectorSource {
}
async getImmutableProperties() {
const vectorFileMeta = await this.getVectorFileMeta();
return [
{
label: getDataSourceLabel(),
@ -56,11 +58,17 @@ export class KibanaRegionmapSource extends AbstractVectorSource {
}),
value: this._descriptor.name,
},
{
label: i18n.translate('xpack.maps.source.kbnRegionMap.vectorLayerUrlLabel', {
defaultMessage: 'Vector layer url',
}),
value: vectorFileMeta.url,
},
];
}
async getVectorFileMeta(): Promise<LayerConfig> {
const regionList: LayerConfig[] = getKibanaRegionList();
const regionList: LayerConfig[] = getRegionmapLayers();
const layerConfig: LayerConfig | undefined = regionList.find(
(regionConfig: LayerConfig) => regionConfig.name === this._descriptor.name
);
@ -107,6 +115,19 @@ export class KibanaRegionmapSource extends AbstractVectorSource {
hasTooltipProperties() {
return true;
}
getSourceTooltipContent() {
return {
tooltipContent: i18n.translate('xpack.maps.source.kbnRegionMap.deprecationTooltipMessage', {
defaultMessage: `'Configured GeoJSON' layer is deprecated. 1) Use 'Upload GeoJSON' to upload '{vectorLayer}'. 2) Use Choropleth layer wizard to build a replacement layer. 3) Finally, delete this layer from your map.`,
values: {
vectorLayer: this._descriptor.name,
},
}),
areResultsTrimmed: false,
isDeprecated: true,
};
}
}
registerSource({

View file

@ -24,6 +24,7 @@ import { DataRequest } from '../../util/data_request';
export interface SourceTooltipConfig {
tooltipContent: string | null;
areResultsTrimmed: boolean;
isDeprecated?: boolean;
}
export type GeoJsonFetchMeta = ESSearchSourceResponseMeta;

View file

@ -7,11 +7,7 @@
import { i18n } from '@kbn/i18n';
import { EMSClient, FileLayer, TMSService } from '@elastic/ems-client';
import { FeatureCollection } from 'geojson';
import * as topojson from 'topojson-client';
import { GeometryCollection } from 'topojson-specification';
import _ from 'lodash';
import fetch from 'node-fetch';
import {
GIS_API_PATH,
EMS_FILES_CATALOGUE_PATH,
@ -19,21 +15,9 @@ import {
EMS_GLYPHS_PATH,
EMS_APP_NAME,
FONTS_API_PATH,
FORMAT_TYPE,
} from '../common/constants';
import {
getHttp,
getRegionmapLayers,
getTilemap,
getKibanaVersion,
getEMSSettings,
} from './kibana_services';
import { getHttp, getTilemap, getKibanaVersion, getEMSSettings } from './kibana_services';
import { getLicenseId } from './licensed_features';
import { LayerConfig } from '../../../../src/plugins/maps_ems/public';
export function getKibanaRegionList(): LayerConfig[] {
return getRegionmapLayers();
}
export function getKibanaTileMap(): unknown {
return getTilemap();
@ -117,41 +101,3 @@ export function getGlyphUrl(): string {
export function isRetina(): boolean {
return window.devicePixelRatio === 2;
}
export async function fetchGeoJson(
fetchUrl: string,
format: FORMAT_TYPE,
featureCollectionPath: string
): Promise<FeatureCollection> {
let fetchedJson;
try {
const response = await fetch(fetchUrl);
if (!response.ok) {
throw new Error('Request failed');
}
fetchedJson = await response.json();
} catch (e) {
throw new Error(
i18n.translate('xpack.maps.util.requestFailedErrorMessage', {
defaultMessage: `Unable to fetch vector shapes from url: {fetchUrl}`,
values: { fetchUrl },
})
);
}
if (format === FORMAT_TYPE.GEOJSON) {
return fetchedJson;
}
if (format === FORMAT_TYPE.TOPOJSON) {
const features = _.get(fetchedJson, `objects.${featureCollectionPath}`) as GeometryCollection;
return topojson.feature(fetchedJson, features);
}
throw new Error(
i18n.translate('xpack.maps.util.formatErrorMessage', {
defaultMessage: `Unable to fetch vector shapes from url: {format}`,
values: { format },
})
);
}

View file

@ -5,6 +5,9 @@
* 2.0.
*/
import _ from 'lodash';
import { i18n } from '@kbn/i18n';
import { AddConfigDeprecation } from '@kbn/config';
import { PluginInitializerContext } from 'src/core/server';
import { PluginConfigDescriptor } from 'kibana/server';
import { MapsPlugin } from './plugin';
@ -21,6 +24,39 @@ export const config: PluginConfigDescriptor<MapsXPackConfig> = {
preserveDrawingBuffer: true,
},
schema: configSchema,
deprecations: () => [
(
completeConfig: Record<string, any>,
rootPath: string,
addDeprecation: AddConfigDeprecation
) => {
if (_.get(completeConfig, 'map.regionmap') === undefined) {
return completeConfig;
}
addDeprecation({
message: i18n.translate('xpack.maps.deprecation.regionmap.message', {
defaultMessage: 'map.regionmap is deprecated and will be removed in 8.0.',
}),
correctiveActions: {
manualSteps: [
i18n.translate('xpack.maps.deprecation.regionmap.step1', {
defaultMessage:
'Remove "map.regionmap" in the Kibana config file, CLI flag, or environment variable (in Docker only).',
}),
i18n.translate('xpack.maps.deprecation.regionmap.step2', {
defaultMessage:
'Use "Upload GeoJSON" to upload each layer defined by "map.regionmap.layers".',
}),
i18n.translate('xpack.maps.deprecation.regionmap.step3', {
defaultMessage:
'Update all maps with "Configured GeoJSON" layers. Use Choropleth layer wizard to build a replacement layer. Delete "Configured GeoJSON" layer from your map.',
}),
],
},
});
return completeConfig;
},
],
};
export const plugin = (initializerContext: PluginInitializerContext) =>

View file

@ -13432,9 +13432,7 @@
"xpack.maps.source.esTopHitsSearch.sortOrderLabel": "並べ替え順",
"xpack.maps.source.geofieldLabel": "地理空間フィールド",
"xpack.maps.source.kbnRegionMap.noConfigErrorMessage": "{name} の map.regionmap 構成が見つかりません",
"xpack.maps.source.kbnRegionMap.noLayerAvailableHelptext": "ベクターレイヤーが利用できません。システム管理者に、kibana.yml で「map.regionmap」を設定するよう依頼してください。",
"xpack.maps.source.kbnRegionMap.vectorLayerLabel": "ベクターレイヤー",
"xpack.maps.source.kbnRegionMapDescription": "kibana.yml で構成された静的ファイルのベクターシェイプです",
"xpack.maps.source.kbnRegionMapTitle": "カスタムベクターシェイプ",
"xpack.maps.source.kbnTMS.kbnTMS.urlLabel": "タイルマップ URL",
"xpack.maps.source.kbnTMS.noConfigErrorMessage": "kibana.yml に map.tilemap.url 構成が見つかりません",
@ -13597,8 +13595,6 @@
"xpack.maps.tutorials.ems.shortDescription": "Elastic Maps Service からの管理ベクターシェイプ。",
"xpack.maps.tutorials.ems.uploadStepText": "1.[Maps] ({newMapUrl}) を開きます。\n2.Add layerをクリックしてからUpload GeoJSONを選択します。\n3.GeoJSON ファイルをアップロードしてImport fileをクリックします。",
"xpack.maps.tutorials.ems.uploadStepTitle": "Elastic Maps Service境界のインデックス作成",
"xpack.maps.util.formatErrorMessage": "URL からベクターシェイプを取得できません:{format}",
"xpack.maps.util.requestFailedErrorMessage": "URL からベクターシェイプを取得できません:{fetchUrl}",
"xpack.maps.validatedNumberInput.invalidClampErrorMessage": "{min} と {max} の間でなければなりません",
"xpack.maps.validatedRange.rangeErrorMessage": "{min} と {max} の間でなければなりません",
"xpack.maps.vector.dualSize.unitLabel": "px",

View file

@ -13610,9 +13610,7 @@
"xpack.maps.source.esTopHitsSearch.sortOrderLabel": "排序顺序",
"xpack.maps.source.geofieldLabel": "地理空间字段",
"xpack.maps.source.kbnRegionMap.noConfigErrorMessage": "找不到 {name} 的 map.regionmap 配置",
"xpack.maps.source.kbnRegionMap.noLayerAvailableHelptext": "没有可用的矢量图层。让您的系统管理员在 kibana.yml 中设置“map.regionmap”。",
"xpack.maps.source.kbnRegionMap.vectorLayerLabel": "矢量图层",
"xpack.maps.source.kbnRegionMapDescription": "来自 kibana.yml 配置的静态文件的矢量形状",
"xpack.maps.source.kbnRegionMapTitle": "定制矢量形状",
"xpack.maps.source.kbnTMS.kbnTMS.urlLabel": "磁贴地图 URL",
"xpack.maps.source.kbnTMS.noConfigErrorMessage": "在 kibana.yml 中找不到 map.tilemap.url 配置",
@ -13775,8 +13773,6 @@
"xpack.maps.tutorials.ems.shortDescription": "来自 Elastic Maps Service 的管理边界。",
"xpack.maps.tutorials.ems.uploadStepText": "1.打开 [Maps]({newMapUrl}).\n2.单击`添加图层`,然后选择`上传 GeoJSON`。\n3.上传 GeoJSON 文件,然后单击`导入文件`。",
"xpack.maps.tutorials.ems.uploadStepTitle": "索引 Elastic Maps Service 边界",
"xpack.maps.util.formatErrorMessage": "无法从以下 URL 获取矢量形状:{format}",
"xpack.maps.util.requestFailedErrorMessage": "无法从以下 URL 获取矢量形状:{fetchUrl}",
"xpack.maps.validatedNumberInput.invalidClampErrorMessage": "必须介于 {min} 和 {max} 之间",
"xpack.maps.validatedRange.rangeErrorMessage": "必须介于 {min} 和 {max} 之间",
"xpack.maps.vector.dualSize.unitLabel": "px",