[Maps] update LayerWizard previewLayer to take layerDescriptor instead of ISource (#64461)
* more changes * remove unused state argument * revert change to make diff easier to follow * migrate pew pew source to new previewLayer * remove createDefaultLayer from ISource * migrate EMS boundaries layer wizard * convert ems tms layer wizard to previewLayer * convert kibana base map to preview layer * convert all other sources to previewLayer * tslint clean-up * remaining ts lint errors * i18n clean up * review feedback Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
dfb6a308cf
commit
399df75821
|
@ -5,27 +5,18 @@
|
||||||
*/
|
*/
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
// Import each layer type, even those not used, to init in registry
|
// Import each layer type, even those not used, to init in registry
|
||||||
|
|
||||||
import '../layers/sources/wms_source';
|
import '../layers/sources/wms_source';
|
||||||
|
|
||||||
import '../layers/sources/ems_file_source';
|
import '../layers/sources/ems_file_source';
|
||||||
|
|
||||||
import '../layers/sources/es_search_source';
|
import '../layers/sources/es_search_source';
|
||||||
|
import '../layers/sources/es_pew_pew_source';
|
||||||
import '../layers/sources/es_pew_pew_source/es_pew_pew_source';
|
|
||||||
|
|
||||||
import '../layers/sources/kibana_regionmap_source';
|
import '../layers/sources/kibana_regionmap_source';
|
||||||
|
|
||||||
import '../layers/sources/es_geo_grid_source';
|
import '../layers/sources/es_geo_grid_source';
|
||||||
|
|
||||||
import '../layers/sources/xyz_tms_source';
|
import '../layers/sources/xyz_tms_source';
|
||||||
|
|
||||||
import { KibanaTilemapSource } from '../layers/sources/kibana_tilemap_source';
|
import { KibanaTilemapSource } from '../layers/sources/kibana_tilemap_source';
|
||||||
|
import { TileLayer } from '../layers/tile_layer';
|
||||||
import { EMSTMSSource } from '../layers/sources/ems_tms_source';
|
import { EMSTMSSource } from '../layers/sources/ems_tms_source';
|
||||||
|
import { VectorTileLayer } from '../layers/vector_tile_layer';
|
||||||
import { getInjectedVarFunc } from '../kibana_services';
|
import { getInjectedVarFunc } from '../kibana_services';
|
||||||
|
|
||||||
import { getKibanaTileMap } from '../meta';
|
import { getKibanaTileMap } from '../meta';
|
||||||
|
|
||||||
export function getInitialLayers(layerListJSON, initialLayers = []) {
|
export function getInitialLayers(layerListJSON, initialLayers = []) {
|
||||||
|
@ -35,18 +26,18 @@ export function getInitialLayers(layerListJSON, initialLayers = []) {
|
||||||
|
|
||||||
const tilemapSourceFromKibana = getKibanaTileMap();
|
const tilemapSourceFromKibana = getKibanaTileMap();
|
||||||
if (_.get(tilemapSourceFromKibana, 'url')) {
|
if (_.get(tilemapSourceFromKibana, 'url')) {
|
||||||
const sourceDescriptor = KibanaTilemapSource.createDescriptor();
|
const layerDescriptor = TileLayer.createDescriptor({
|
||||||
const source = new KibanaTilemapSource(sourceDescriptor);
|
sourceDescriptor: KibanaTilemapSource.createDescriptor(),
|
||||||
const layer = source.createDefaultLayer();
|
});
|
||||||
return [layer.toLayerDescriptor(), ...initialLayers];
|
return [layerDescriptor, ...initialLayers];
|
||||||
}
|
}
|
||||||
|
|
||||||
const isEmsEnabled = getInjectedVarFunc()('isEmsEnabled', true);
|
const isEmsEnabled = getInjectedVarFunc()('isEmsEnabled', true);
|
||||||
if (isEmsEnabled) {
|
if (isEmsEnabled) {
|
||||||
const descriptor = EMSTMSSource.createDescriptor({ isAutoSelect: true });
|
const layerDescriptor = VectorTileLayer.createDescriptor({
|
||||||
const source = new EMSTMSSource(descriptor);
|
sourceDescriptor: EMSTMSSource.createDescriptor({ isAutoSelect: true }),
|
||||||
const layer = source.createDefaultLayer();
|
});
|
||||||
return [layer.toLayerDescriptor(), ...initialLayers];
|
return [layerDescriptor, ...initialLayers];
|
||||||
}
|
}
|
||||||
|
|
||||||
return initialLayers;
|
return initialLayers;
|
||||||
|
|
|
@ -4,51 +4,36 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { Fragment } from 'react';
|
import React from 'react';
|
||||||
import { EuiSpacer, EuiPanel, EuiButtonEmpty } from '@elastic/eui';
|
import { EuiPanel } from '@elastic/eui';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
|
||||||
|
|
||||||
import { uploadLayerWizardConfig } from '../../../layers/sources/client_file_source';
|
import { uploadLayerWizardConfig } from '../../../layers/sources/client_file_source';
|
||||||
|
|
||||||
export const ImportEditor = ({ clearSource, isIndexingTriggered, ...props }) => {
|
export const ImportEditor = props => {
|
||||||
const editorProperties = getEditorProperties({ isIndexingTriggered, ...props });
|
const editorProperties = getEditorProperties(props);
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<EuiPanel style={{ position: 'relative' }}>
|
||||||
{isIndexingTriggered ? null : (
|
{uploadLayerWizardConfig.renderWizard(editorProperties)}
|
||||||
<Fragment>
|
</EuiPanel>
|
||||||
<EuiButtonEmpty size="xs" flush="left" onClick={clearSource} iconType="arrowLeft">
|
|
||||||
<FormattedMessage
|
|
||||||
id="xpack.maps.addLayerPanel.changeDataSourceButtonLabel"
|
|
||||||
defaultMessage="Change data source"
|
|
||||||
/>
|
|
||||||
</EuiButtonEmpty>
|
|
||||||
<EuiSpacer size="s" />
|
|
||||||
</Fragment>
|
|
||||||
)}
|
|
||||||
<EuiPanel style={{ position: 'relative' }}>
|
|
||||||
{uploadLayerWizardConfig.renderWizard(editorProperties)}
|
|
||||||
</EuiPanel>
|
|
||||||
</Fragment>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
function getEditorProperties({
|
function getEditorProperties({
|
||||||
inspectorAdapters,
|
previewLayer,
|
||||||
|
mapColors,
|
||||||
onRemove,
|
onRemove,
|
||||||
viewLayer,
|
|
||||||
isIndexingTriggered,
|
isIndexingTriggered,
|
||||||
onIndexReady,
|
onIndexReady,
|
||||||
importSuccessHandler,
|
importSuccessHandler,
|
||||||
importErrorHandler,
|
importErrorHandler,
|
||||||
}) {
|
}) {
|
||||||
return {
|
return {
|
||||||
onPreviewSource: viewLayer,
|
previewLayer,
|
||||||
inspectorAdapters,
|
mapColors,
|
||||||
onRemove,
|
onRemove,
|
||||||
importSuccessHandler,
|
importSuccessHandler,
|
||||||
importErrorHandler,
|
importErrorHandler,
|
||||||
isIndexingTriggered,
|
isIndexingTriggered,
|
||||||
addAndViewSource: viewLayer,
|
|
||||||
onIndexReady,
|
onIndexReady,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,12 +34,12 @@ function mapStateToProps(state = {}) {
|
||||||
|
|
||||||
function mapDispatchToProps(dispatch) {
|
function mapDispatchToProps(dispatch) {
|
||||||
return {
|
return {
|
||||||
viewLayer: async layer => {
|
previewLayer: async layerDescriptor => {
|
||||||
await dispatch(setSelectedLayer(null));
|
await dispatch(setSelectedLayer(null));
|
||||||
await dispatch(removeTransientLayer());
|
await dispatch(removeTransientLayer());
|
||||||
dispatch(addLayer(layer.toLayerDescriptor()));
|
dispatch(addLayer(layerDescriptor));
|
||||||
dispatch(setSelectedLayer(layer.getId()));
|
dispatch(setSelectedLayer(layerDescriptor.id));
|
||||||
dispatch(setTransientLayer(layer.getId()));
|
dispatch(setTransientLayer(layerDescriptor.id));
|
||||||
},
|
},
|
||||||
removeTransientLayer: () => {
|
removeTransientLayer: () => {
|
||||||
dispatch(setSelectedLayer(null));
|
dispatch(setSelectedLayer(null));
|
||||||
|
|
|
@ -1,19 +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;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { SourceEditor } from './view';
|
|
||||||
|
|
||||||
import { getInspectorAdapters } from '../../../reducers/non_serializable_instances';
|
|
||||||
|
|
||||||
function mapStateToProps(state = {}) {
|
|
||||||
return {
|
|
||||||
inspectorAdapters: getInspectorAdapters(state),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const connectedFlyOut = connect(mapStateToProps)(SourceEditor);
|
|
||||||
export { connectedFlyOut as SourceEditor };
|
|
|
@ -1,40 +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;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React, { Fragment } from 'react';
|
|
||||||
import { EuiSpacer, EuiPanel, EuiButtonEmpty } from '@elastic/eui';
|
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
|
||||||
|
|
||||||
export const SourceEditor = ({
|
|
||||||
clearSource,
|
|
||||||
layerWizard,
|
|
||||||
isIndexingTriggered,
|
|
||||||
inspectorAdapters,
|
|
||||||
previewLayer,
|
|
||||||
}) => {
|
|
||||||
if (!layerWizard) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Fragment>
|
|
||||||
{isIndexingTriggered ? null : (
|
|
||||||
<Fragment>
|
|
||||||
<EuiButtonEmpty size="xs" flush="left" onClick={clearSource} iconType="arrowLeft">
|
|
||||||
<FormattedMessage
|
|
||||||
id="xpack.maps.addLayerPanel.changeDataSourceButtonLabel"
|
|
||||||
defaultMessage="Change data source"
|
|
||||||
/>
|
|
||||||
</EuiButtonEmpty>
|
|
||||||
<EuiSpacer size="s" />
|
|
||||||
</Fragment>
|
|
||||||
)}
|
|
||||||
<EuiPanel>
|
|
||||||
{layerWizard.renderWizard({ onPreviewSource: previewLayer, inspectorAdapters })}
|
|
||||||
</EuiPanel>
|
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -7,8 +7,7 @@
|
||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
|
|
||||||
import { getLayerWizards } from '../../../layers/layer_wizard_registry';
|
import { getLayerWizards } from '../../../layers/layer_wizard_registry';
|
||||||
import { EuiTitle, EuiSpacer, EuiCard, EuiIcon } from '@elastic/eui';
|
import { EuiSpacer, EuiCard, EuiIcon } from '@elastic/eui';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
export function SourceSelect({ updateSourceSelection }) {
|
export function SourceSelect({ updateSourceSelection }) {
|
||||||
|
@ -38,17 +37,5 @@ export function SourceSelect({ updateSourceSelection }) {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return <Fragment>{sourceCards}</Fragment>;
|
||||||
<Fragment>
|
|
||||||
<EuiTitle size="xs">
|
|
||||||
<h2>
|
|
||||||
<FormattedMessage
|
|
||||||
id="xpack.maps.addLayerPanel.chooseDataSourceTitle"
|
|
||||||
defaultMessage="Choose data source"
|
|
||||||
/>
|
|
||||||
</h2>
|
|
||||||
</EuiTitle>
|
|
||||||
{sourceCards}
|
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,18 +4,19 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import { SourceSelect } from './source_select/source_select';
|
import { SourceSelect } from './source_select/source_select';
|
||||||
import { FlyoutFooter } from './flyout_footer';
|
import { FlyoutFooter } from './flyout_footer';
|
||||||
import { SourceEditor } from './source_editor';
|
|
||||||
import { ImportEditor } from './import_editor';
|
import { ImportEditor } from './import_editor';
|
||||||
import { EuiFlexGroup, EuiTitle, EuiFlyoutHeader } from '@elastic/eui';
|
import { EuiButtonEmpty, EuiPanel, EuiTitle, EuiFlyoutHeader, EuiSpacer } from '@elastic/eui';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
export class AddLayerPanel extends Component {
|
export class AddLayerPanel extends Component {
|
||||||
state = {
|
state = {
|
||||||
layerWizard: null,
|
layerWizard: null,
|
||||||
layer: null,
|
layerDescriptor: null, // TODO get this from redux store instead of storing locally
|
||||||
|
isIndexingSource: false,
|
||||||
importView: false,
|
importView: false,
|
||||||
layerImportAddReady: false,
|
layerImportAddReady: false,
|
||||||
};
|
};
|
||||||
|
@ -35,13 +36,9 @@ export class AddLayerPanel extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
_getPanelDescription() {
|
_getPanelDescription() {
|
||||||
const { layerWizard, importView, layerImportAddReady } = this.state;
|
const { importView, layerImportAddReady } = this.state;
|
||||||
let panelDescription;
|
let panelDescription;
|
||||||
if (!layerWizard) {
|
if (layerImportAddReady || !importView) {
|
||||||
panelDescription = i18n.translate('xpack.maps.addLayerPanel.selectSource', {
|
|
||||||
defaultMessage: 'Select source',
|
|
||||||
});
|
|
||||||
} else if (layerImportAddReady || !importView) {
|
|
||||||
panelDescription = i18n.translate('xpack.maps.addLayerPanel.addLayer', {
|
panelDescription = i18n.translate('xpack.maps.addLayerPanel.addLayer', {
|
||||||
defaultMessage: 'Add layer',
|
defaultMessage: 'Add layer',
|
||||||
});
|
});
|
||||||
|
@ -53,29 +50,21 @@ export class AddLayerPanel extends Component {
|
||||||
return panelDescription;
|
return panelDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
_viewLayer = async (source, options = {}) => {
|
_previewLayer = async (layerDescriptor, isIndexingSource) => {
|
||||||
if (!this._isMounted) {
|
if (!this._isMounted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!source) {
|
if (!layerDescriptor) {
|
||||||
this.setState({ layer: null });
|
this.setState({
|
||||||
|
layerDescriptor: null,
|
||||||
|
isIndexingSource: false,
|
||||||
|
});
|
||||||
this.props.removeTransientLayer();
|
this.props.removeTransientLayer();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const styleDescriptor =
|
this.setState({ layerDescriptor, isIndexingSource });
|
||||||
this.state.layer && this.state.layer.getCurrentStyle()
|
this.props.previewLayer(layerDescriptor);
|
||||||
? this.state.layer.getCurrentStyle().getDescriptor()
|
|
||||||
: null;
|
|
||||||
const layerInitProps = {
|
|
||||||
...options,
|
|
||||||
style: styleDescriptor,
|
|
||||||
};
|
|
||||||
const newLayer = source.createDefaultLayer(layerInitProps, this.props.mapColors);
|
|
||||||
if (!this._isMounted) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.setState({ layer: newLayer }, () => this.props.viewLayer(this.state.layer));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_clearLayerData = ({ keepSourceType = false }) => {
|
_clearLayerData = ({ keepSourceType = false }) => {
|
||||||
|
@ -84,7 +73,8 @@ export class AddLayerPanel extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
layer: null,
|
layerDescriptor: null,
|
||||||
|
isIndexingSource: false,
|
||||||
...(!keepSourceType ? { layerWizard: null, importView: false } : {}),
|
...(!keepSourceType ? { layerWizard: null, importView: false } : {}),
|
||||||
});
|
});
|
||||||
this.props.removeTransientLayer();
|
this.props.removeTransientLayer();
|
||||||
|
@ -95,72 +85,75 @@ export class AddLayerPanel extends Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
_layerAddHandler = () => {
|
_layerAddHandler = () => {
|
||||||
const {
|
if (this.state.isIndexingSource && !this.props.isIndexingTriggered) {
|
||||||
isIndexingTriggered,
|
this.props.setIndexingTriggered();
|
||||||
setIndexingTriggered,
|
|
||||||
selectLayerAndAdd,
|
|
||||||
resetIndexing,
|
|
||||||
} = this.props;
|
|
||||||
const layerSource = this.state.layer.getSource();
|
|
||||||
const boolIndexLayer = layerSource.shouldBeIndexed();
|
|
||||||
this.setState({ layer: null });
|
|
||||||
if (boolIndexLayer && !isIndexingTriggered) {
|
|
||||||
setIndexingTriggered();
|
|
||||||
} else {
|
} else {
|
||||||
selectLayerAndAdd();
|
this.props.selectLayerAndAdd();
|
||||||
if (this.state.importView) {
|
if (this.state.importView) {
|
||||||
this.setState({
|
this.setState({
|
||||||
layerImportAddReady: false,
|
layerImportAddReady: false,
|
||||||
});
|
});
|
||||||
resetIndexing();
|
this.props.resetIndexing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_renderAddLayerPanel() {
|
_renderPanelBody() {
|
||||||
const { layerWizard, importView } = this.state;
|
if (!this.state.layerWizard) {
|
||||||
if (!layerWizard) {
|
|
||||||
return <SourceSelect updateSourceSelection={this._onSourceSelectionChange} />;
|
return <SourceSelect updateSourceSelection={this._onSourceSelectionChange} />;
|
||||||
}
|
}
|
||||||
if (importView) {
|
|
||||||
|
const backButton = this.props.isIndexingTriggered ? null : (
|
||||||
|
<Fragment>
|
||||||
|
<EuiButtonEmpty size="xs" flush="left" onClick={this._clearLayerData} iconType="arrowLeft">
|
||||||
|
<FormattedMessage
|
||||||
|
id="xpack.maps.addLayerPanel.changeDataSourceButtonLabel"
|
||||||
|
defaultMessage="Change layer"
|
||||||
|
/>
|
||||||
|
</EuiButtonEmpty>
|
||||||
|
<EuiSpacer size="s" />
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (this.state.importView) {
|
||||||
return (
|
return (
|
||||||
<ImportEditor
|
<Fragment>
|
||||||
clearSource={this._clearLayerData}
|
{backButton}
|
||||||
viewLayer={this._viewLayer}
|
<ImportEditor
|
||||||
onRemove={() => this._clearLayerData({ keepSourceType: true })}
|
clearSource={this._clearLayerData}
|
||||||
/>
|
previewLayer={this._previewLayer}
|
||||||
|
mapColors={this.props.mapColors}
|
||||||
|
onRemove={() => this._clearLayerData({ keepSourceType: true })}
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SourceEditor
|
<Fragment>
|
||||||
clearSource={this._clearLayerData}
|
{backButton}
|
||||||
layerWizard={layerWizard}
|
<EuiPanel>
|
||||||
previewLayer={this._viewLayer}
|
{this.state.layerWizard.renderWizard({
|
||||||
/>
|
previewLayer: this._previewLayer,
|
||||||
|
mapColors: this.props.mapColors,
|
||||||
|
})}
|
||||||
|
</EuiPanel>
|
||||||
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderFooter(buttonDescription) {
|
render() {
|
||||||
const { importView, layer } = this.state;
|
if (!this.props.flyoutVisible) {
|
||||||
const { isIndexingReady, isIndexingSuccess } = this.props;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const buttonEnabled = importView ? isIndexingReady || isIndexingSuccess : !!layer;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FlyoutFooter
|
|
||||||
showNextButton={!!this.state.layerWizard}
|
|
||||||
disableNextButton={!buttonEnabled}
|
|
||||||
onClick={this._layerAddHandler}
|
|
||||||
nextButtonText={buttonDescription}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
_renderFlyout() {
|
|
||||||
const panelDescription = this._getPanelDescription();
|
const panelDescription = this._getPanelDescription();
|
||||||
|
const isNextBtnEnabled = this.state.importView
|
||||||
|
? this.props.isIndexingReady || this.props.isIndexingSuccess
|
||||||
|
: !!this.state.layerDescriptor;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EuiFlexGroup direction="column" gutterSize="none">
|
<Fragment>
|
||||||
<EuiFlyoutHeader hasBorder className="mapLayerPanel__header">
|
<EuiFlyoutHeader hasBorder className="mapLayerPanel__header">
|
||||||
<EuiTitle size="s">
|
<EuiTitle size="s">
|
||||||
<h2>{panelDescription}</h2>
|
<h2>{panelDescription}</h2>
|
||||||
|
@ -168,14 +161,16 @@ export class AddLayerPanel extends Component {
|
||||||
</EuiFlyoutHeader>
|
</EuiFlyoutHeader>
|
||||||
|
|
||||||
<div className="mapLayerPanel__body" data-test-subj="layerAddForm">
|
<div className="mapLayerPanel__body" data-test-subj="layerAddForm">
|
||||||
<div className="mapLayerPanel__bodyOverflow">{this._renderAddLayerPanel()}</div>
|
<div className="mapLayerPanel__bodyOverflow">{this._renderPanelBody()}</div>
|
||||||
</div>
|
</div>
|
||||||
{this._renderFooter(panelDescription)}
|
|
||||||
</EuiFlexGroup>
|
<FlyoutFooter
|
||||||
|
showNextButton={!!this.state.layerWizard}
|
||||||
|
disableNextButton={!isNextBtnEnabled}
|
||||||
|
onClick={this._layerAddHandler}
|
||||||
|
nextButtonText={panelDescription}
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
|
||||||
return this.props.flyoutVisible ? this._renderFlyout() : null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,7 +156,7 @@ export class BlendedVectorLayer extends VectorLayer implements IVectorLayer {
|
||||||
static type = LAYER_TYPE.BLENDED_VECTOR;
|
static type = LAYER_TYPE.BLENDED_VECTOR;
|
||||||
|
|
||||||
static createDescriptor(
|
static createDescriptor(
|
||||||
options: VectorLayerDescriptor,
|
options: Partial<VectorLayerDescriptor>,
|
||||||
mapColors: string[]
|
mapColors: string[]
|
||||||
): VectorLayerDescriptor {
|
): VectorLayerDescriptor {
|
||||||
const layerDescriptor = VectorLayer.createDescriptor(options, mapColors);
|
const layerDescriptor = VectorLayer.createDescriptor(options, mapColors);
|
||||||
|
|
|
@ -62,7 +62,6 @@ export interface ILayer {
|
||||||
isLayerLoading(): boolean;
|
isLayerLoading(): boolean;
|
||||||
hasErrors(): boolean;
|
hasErrors(): boolean;
|
||||||
getErrors(): string;
|
getErrors(): string;
|
||||||
toLayerDescriptor(): LayerDescriptor;
|
|
||||||
getMbLayerIds(): string[];
|
getMbLayerIds(): string[];
|
||||||
ownsMbLayerId(mbLayerId: string): boolean;
|
ownsMbLayerId(mbLayerId: string): boolean;
|
||||||
ownsMbSourceId(mbSourceId: string): boolean;
|
ownsMbSourceId(mbSourceId: string): boolean;
|
||||||
|
@ -413,10 +412,6 @@ export class AbstractLayer implements ILayer {
|
||||||
: '';
|
: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
toLayerDescriptor(): LayerDescriptor {
|
|
||||||
return this._descriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
async syncData(syncContext: SyncContext) {
|
async syncData(syncContext: SyncContext) {
|
||||||
// no-op by default
|
// no-op by default
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,17 @@
|
||||||
/* eslint-disable @typescript-eslint/consistent-type-definitions */
|
/* eslint-disable @typescript-eslint/consistent-type-definitions */
|
||||||
|
|
||||||
import { ReactElement } from 'react';
|
import { ReactElement } from 'react';
|
||||||
import { ISource } from './sources/source';
|
import { LayerDescriptor } from '../../common/descriptor_types';
|
||||||
|
|
||||||
export type PreviewSourceHandler = (source: ISource | null) => void;
|
|
||||||
|
|
||||||
export type RenderWizardArguments = {
|
export type RenderWizardArguments = {
|
||||||
onPreviewSource: PreviewSourceHandler;
|
previewLayer: (layerDescriptor: LayerDescriptor | null, isIndexingSource?: boolean) => void;
|
||||||
inspectorAdapters: object;
|
mapColors: string[];
|
||||||
|
// upload arguments
|
||||||
|
isIndexingTriggered: boolean;
|
||||||
|
onRemove: () => void;
|
||||||
|
onIndexReady: () => void;
|
||||||
|
importSuccessHandler: (indexResponses: unknown) => void;
|
||||||
|
importErrorHandler: (indexResponses: unknown) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LayerWizard = {
|
export type LayerWizard = {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { esDocumentsLayerWizardConfig } from './sources/es_search_source';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { clustersLayerWizardConfig, heatmapLayerWizardConfig } from './sources/es_geo_grid_source';
|
import { clustersLayerWizardConfig, heatmapLayerWizardConfig } from './sources/es_geo_grid_source';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { point2PointLayerWizardConfig } from './sources/es_pew_pew_source/es_pew_pew_source';
|
import { point2PointLayerWizardConfig } from './sources/es_pew_pew_source';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { emsBoundariesLayerWizardConfig } from './sources/ems_file_source';
|
import { emsBoundariesLayerWizardConfig } from './sources/ems_file_source';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|
|
@ -5,17 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { AbstractVectorSource } from '../vector_source';
|
import { AbstractVectorSource } from '../vector_source';
|
||||||
import React from 'react';
|
import { SOURCE_TYPES } from '../../../../common/constants';
|
||||||
import {
|
|
||||||
ES_GEO_FIELD_TYPE,
|
|
||||||
SOURCE_TYPES,
|
|
||||||
DEFAULT_MAX_RESULT_WINDOW,
|
|
||||||
SCALING_TYPES,
|
|
||||||
} from '../../../../common/constants';
|
|
||||||
import { ClientFileCreateSourceEditor } from './create_client_file_source_editor';
|
|
||||||
import { ESSearchSource } from '../es_search_source';
|
|
||||||
import uuid from 'uuid/v4';
|
|
||||||
import { i18n } from '@kbn/i18n';
|
|
||||||
import { registerSource } from '../source_registry';
|
import { registerSource } from '../source_registry';
|
||||||
|
|
||||||
export class GeojsonFileSource extends AbstractVectorSource {
|
export class GeojsonFileSource extends AbstractVectorSource {
|
||||||
|
@ -66,103 +56,9 @@ export class GeojsonFileSource extends AbstractVectorSource {
|
||||||
canFormatFeatureProperties() {
|
canFormatFeatureProperties() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldBeIndexed() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const viewIndexedData = (
|
|
||||||
addAndViewSource,
|
|
||||||
inspectorAdapters,
|
|
||||||
importSuccessHandler,
|
|
||||||
importErrorHandler
|
|
||||||
) => {
|
|
||||||
return (indexResponses = {}) => {
|
|
||||||
const { indexDataResp, indexPatternResp } = indexResponses;
|
|
||||||
|
|
||||||
const indexCreationFailed = !(indexDataResp && indexDataResp.success);
|
|
||||||
const allDocsFailed = indexDataResp.failures.length === indexDataResp.docCount;
|
|
||||||
const indexPatternCreationFailed = !(indexPatternResp && indexPatternResp.success);
|
|
||||||
|
|
||||||
if (indexCreationFailed || allDocsFailed || indexPatternCreationFailed) {
|
|
||||||
importErrorHandler(indexResponses);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { fields, id: indexPatternId } = indexPatternResp;
|
|
||||||
const geoField = fields.find(field => Object.values(ES_GEO_FIELD_TYPE).includes(field.type));
|
|
||||||
if (!indexPatternId || !geoField) {
|
|
||||||
addAndViewSource(null);
|
|
||||||
} else {
|
|
||||||
const source = new ESSearchSource(
|
|
||||||
{
|
|
||||||
id: uuid(),
|
|
||||||
indexPatternId,
|
|
||||||
geoField: geoField.name,
|
|
||||||
// Only turn on bounds filter for large doc counts
|
|
||||||
filterByMapBounds: indexDataResp.docCount > DEFAULT_MAX_RESULT_WINDOW,
|
|
||||||
scalingType:
|
|
||||||
geoField.type === ES_GEO_FIELD_TYPE.GEO_POINT
|
|
||||||
? SCALING_TYPES.CLUSTERS
|
|
||||||
: SCALING_TYPES.LIMIT,
|
|
||||||
},
|
|
||||||
inspectorAdapters
|
|
||||||
);
|
|
||||||
addAndViewSource(source);
|
|
||||||
importSuccessHandler(indexResponses);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const previewGeojsonFile = (onPreviewSource, inspectorAdapters) => {
|
|
||||||
return (geojsonFile, name) => {
|
|
||||||
if (!geojsonFile) {
|
|
||||||
onPreviewSource(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const sourceDescriptor = GeojsonFileSource.createDescriptor(geojsonFile, name);
|
|
||||||
const source = new GeojsonFileSource(sourceDescriptor, inspectorAdapters);
|
|
||||||
onPreviewSource(source);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
registerSource({
|
registerSource({
|
||||||
ConstructorFunction: GeojsonFileSource,
|
ConstructorFunction: GeojsonFileSource,
|
||||||
type: SOURCE_TYPES.GEOJSON_FILE,
|
type: SOURCE_TYPES.GEOJSON_FILE,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const uploadLayerWizardConfig = {
|
|
||||||
description: i18n.translate('xpack.maps.source.geojsonFileDescription', {
|
|
||||||
defaultMessage: 'Index GeoJSON data in Elasticsearch',
|
|
||||||
}),
|
|
||||||
icon: 'importAction',
|
|
||||||
isIndexingSource: true,
|
|
||||||
renderWizard: ({
|
|
||||||
onPreviewSource,
|
|
||||||
inspectorAdapters,
|
|
||||||
addAndViewSource,
|
|
||||||
isIndexingTriggered,
|
|
||||||
onRemove,
|
|
||||||
onIndexReady,
|
|
||||||
importSuccessHandler,
|
|
||||||
importErrorHandler,
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<ClientFileCreateSourceEditor
|
|
||||||
previewGeojsonFile={previewGeojsonFile(onPreviewSource, inspectorAdapters)}
|
|
||||||
isIndexingTriggered={isIndexingTriggered}
|
|
||||||
onIndexingComplete={viewIndexedData(
|
|
||||||
addAndViewSource,
|
|
||||||
inspectorAdapters,
|
|
||||||
importSuccessHandler,
|
|
||||||
importErrorHandler
|
|
||||||
)}
|
|
||||||
onRemove={onRemove}
|
|
||||||
onIndexReady={onIndexReady}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
title: i18n.translate('xpack.maps.source.geojsonFileTitle', {
|
|
||||||
defaultMessage: 'Upload GeoJSON',
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
|
@ -4,4 +4,5 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { GeojsonFileSource, uploadLayerWizardConfig } from './geojson_file_source';
|
export { GeojsonFileSource } from './geojson_file_source';
|
||||||
|
export { uploadLayerWizardConfig } from './upload_layer_wizard';
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import React from 'react';
|
||||||
|
import { IFieldType } from 'src/plugins/data/public';
|
||||||
|
import {
|
||||||
|
ES_GEO_FIELD_TYPE,
|
||||||
|
DEFAULT_MAX_RESULT_WINDOW,
|
||||||
|
SCALING_TYPES,
|
||||||
|
} from '../../../../common/constants';
|
||||||
|
// @ts-ignore
|
||||||
|
import { ESSearchSource, createDefaultLayerDescriptor } from '../es_search_source';
|
||||||
|
import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry';
|
||||||
|
// @ts-ignore
|
||||||
|
import { ClientFileCreateSourceEditor } from './create_client_file_source_editor';
|
||||||
|
// @ts-ignore
|
||||||
|
import { GeojsonFileSource } from './geojson_file_source';
|
||||||
|
import { VectorLayer } from '../../vector_layer';
|
||||||
|
|
||||||
|
export const uploadLayerWizardConfig: LayerWizard = {
|
||||||
|
description: i18n.translate('xpack.maps.source.geojsonFileDescription', {
|
||||||
|
defaultMessage: 'Index GeoJSON data in Elasticsearch',
|
||||||
|
}),
|
||||||
|
icon: 'importAction',
|
||||||
|
isIndexingSource: true,
|
||||||
|
renderWizard: ({
|
||||||
|
previewLayer,
|
||||||
|
mapColors,
|
||||||
|
isIndexingTriggered,
|
||||||
|
onRemove,
|
||||||
|
onIndexReady,
|
||||||
|
importSuccessHandler,
|
||||||
|
importErrorHandler,
|
||||||
|
}: RenderWizardArguments) => {
|
||||||
|
function previewGeojsonFile(geojsonFile: unknown, name: string) {
|
||||||
|
if (!geojsonFile) {
|
||||||
|
previewLayer(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const sourceDescriptor = GeojsonFileSource.createDescriptor(geojsonFile, name);
|
||||||
|
const layerDescriptor = VectorLayer.createDescriptor({ sourceDescriptor }, mapColors);
|
||||||
|
// TODO figure out a better way to handle passing this information back to layer_addpanel
|
||||||
|
previewLayer(layerDescriptor, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function viewIndexedData(indexResponses: {
|
||||||
|
indexDataResp: unknown;
|
||||||
|
indexPatternResp: unknown;
|
||||||
|
}) {
|
||||||
|
const { indexDataResp, indexPatternResp } = indexResponses;
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const indexCreationFailed = !(indexDataResp && indexDataResp.success);
|
||||||
|
// @ts-ignore
|
||||||
|
const allDocsFailed = indexDataResp.failures.length === indexDataResp.docCount;
|
||||||
|
// @ts-ignore
|
||||||
|
const indexPatternCreationFailed = !(indexPatternResp && indexPatternResp.success);
|
||||||
|
|
||||||
|
if (indexCreationFailed || allDocsFailed || indexPatternCreationFailed) {
|
||||||
|
importErrorHandler(indexResponses);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
const { fields, id: indexPatternId } = indexPatternResp;
|
||||||
|
const geoField = fields.find((field: IFieldType) =>
|
||||||
|
[ES_GEO_FIELD_TYPE.GEO_POINT as string, ES_GEO_FIELD_TYPE.GEO_SHAPE as string].includes(
|
||||||
|
field.type
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if (!indexPatternId || !geoField) {
|
||||||
|
previewLayer(null);
|
||||||
|
} else {
|
||||||
|
const esSearchSourceConfig = {
|
||||||
|
indexPatternId,
|
||||||
|
geoField: geoField.name,
|
||||||
|
// Only turn on bounds filter for large doc counts
|
||||||
|
// @ts-ignore
|
||||||
|
filterByMapBounds: indexDataResp.docCount > DEFAULT_MAX_RESULT_WINDOW,
|
||||||
|
scalingType:
|
||||||
|
geoField.type === ES_GEO_FIELD_TYPE.GEO_POINT
|
||||||
|
? SCALING_TYPES.CLUSTERS
|
||||||
|
: SCALING_TYPES.LIMIT,
|
||||||
|
};
|
||||||
|
previewLayer(createDefaultLayerDescriptor(esSearchSourceConfig, mapColors));
|
||||||
|
importSuccessHandler(indexResponses);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ClientFileCreateSourceEditor
|
||||||
|
previewGeojsonFile={previewGeojsonFile}
|
||||||
|
isIndexingTriggered={isIndexingTriggered}
|
||||||
|
onIndexingComplete={viewIndexedData}
|
||||||
|
onRemove={onRemove}
|
||||||
|
onIndexReady={onIndexReady}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
title: i18n.translate('xpack.maps.source.geojsonFileTitle', {
|
||||||
|
defaultMessage: 'Upload GeoJSON',
|
||||||
|
}),
|
||||||
|
};
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import { VectorLayer } from '../../vector_layer';
|
||||||
|
import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry';
|
||||||
|
// @ts-ignore
|
||||||
|
import { EMSFileCreateSourceEditor } from './create_source_editor';
|
||||||
|
// @ts-ignore
|
||||||
|
import { EMSFileSource, sourceTitle } from './ems_file_source';
|
||||||
|
|
||||||
|
export const emsBoundariesLayerWizardConfig: LayerWizard = {
|
||||||
|
description: i18n.translate('xpack.maps.source.emsFileDescription', {
|
||||||
|
defaultMessage: 'Administrative boundaries from Elastic Maps Service',
|
||||||
|
}),
|
||||||
|
icon: 'emsApp',
|
||||||
|
renderWizard: ({ previewLayer, mapColors }: RenderWizardArguments) => {
|
||||||
|
const onSourceConfigChange = (sourceConfig: unknown) => {
|
||||||
|
// @ts-ignore
|
||||||
|
const sourceDescriptor = EMSFileSource.createDescriptor(sourceConfig);
|
||||||
|
const layerDescriptor = VectorLayer.createDescriptor({ sourceDescriptor }, mapColors);
|
||||||
|
previewLayer(layerDescriptor);
|
||||||
|
};
|
||||||
|
return <EMSFileCreateSourceEditor onSourceConfigChange={onSourceConfigChange} />;
|
||||||
|
},
|
||||||
|
title: sourceTitle,
|
||||||
|
};
|
|
@ -9,14 +9,13 @@ import { VECTOR_SHAPE_TYPES } from '../vector_feature_types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { SOURCE_TYPES, FIELD_ORIGIN } from '../../../../common/constants';
|
import { SOURCE_TYPES, FIELD_ORIGIN } from '../../../../common/constants';
|
||||||
import { getEMSClient } from '../../../meta';
|
import { getEMSClient } from '../../../meta';
|
||||||
import { EMSFileCreateSourceEditor } from './create_source_editor';
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { getDataSourceLabel } from '../../../../common/i18n_getters';
|
import { getDataSourceLabel } from '../../../../common/i18n_getters';
|
||||||
import { UpdateSourceEditor } from './update_source_editor';
|
import { UpdateSourceEditor } from './update_source_editor';
|
||||||
import { EMSFileField } from '../../fields/ems_file_field';
|
import { EMSFileField } from '../../fields/ems_file_field';
|
||||||
import { registerSource } from '../source_registry';
|
import { registerSource } from '../source_registry';
|
||||||
|
|
||||||
const sourceTitle = i18n.translate('xpack.maps.source.emsFileTitle', {
|
export const sourceTitle = i18n.translate('xpack.maps.source.emsFileTitle', {
|
||||||
defaultMessage: 'EMS Boundaries',
|
defaultMessage: 'EMS Boundaries',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -161,19 +160,3 @@ registerSource({
|
||||||
ConstructorFunction: EMSFileSource,
|
ConstructorFunction: EMSFileSource,
|
||||||
type: SOURCE_TYPES.EMS_FILE,
|
type: SOURCE_TYPES.EMS_FILE,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const emsBoundariesLayerWizardConfig = {
|
|
||||||
description: i18n.translate('xpack.maps.source.emsFileDescription', {
|
|
||||||
defaultMessage: 'Administrative boundaries from Elastic Maps Service',
|
|
||||||
}),
|
|
||||||
icon: 'emsApp',
|
|
||||||
renderWizard: ({ onPreviewSource, inspectorAdapters }) => {
|
|
||||||
const onSourceConfigChange = sourceConfig => {
|
|
||||||
const sourceDescriptor = EMSFileSource.createDescriptor(sourceConfig);
|
|
||||||
const source = new EMSFileSource(sourceDescriptor, inspectorAdapters);
|
|
||||||
onPreviewSource(source);
|
|
||||||
};
|
|
||||||
return <EMSFileCreateSourceEditor onSourceConfigChange={onSourceConfigChange} />;
|
|
||||||
},
|
|
||||||
title: sourceTitle,
|
|
||||||
};
|
|
||||||
|
|
|
@ -4,4 +4,5 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { EMSFileSource, emsBoundariesLayerWizardConfig } from './ems_file_source';
|
export { emsBoundariesLayerWizardConfig } from './ems_boundaries_layer_wizard';
|
||||||
|
export { EMSFileSource } from './ems_file_source';
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
import React from 'react';
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry';
|
||||||
|
// @ts-ignore
|
||||||
|
import { EMSTMSSource, sourceTitle } from './ems_tms_source';
|
||||||
|
// @ts-ignore
|
||||||
|
import { VectorTileLayer } from '../../vector_tile_layer';
|
||||||
|
// @ts-ignore
|
||||||
|
import { TileServiceSelect } from './tile_service_select';
|
||||||
|
|
||||||
|
export const emsBaseMapLayerWizardConfig: LayerWizard = {
|
||||||
|
description: i18n.translate('xpack.maps.source.emsTileDescription', {
|
||||||
|
defaultMessage: 'Tile map service from Elastic Maps Service',
|
||||||
|
}),
|
||||||
|
icon: 'emsApp',
|
||||||
|
renderWizard: ({ previewLayer }: RenderWizardArguments) => {
|
||||||
|
const onSourceConfigChange = (sourceConfig: unknown) => {
|
||||||
|
const layerDescriptor = VectorTileLayer.createDescriptor({
|
||||||
|
sourceDescriptor: EMSTMSSource.createDescriptor(sourceConfig),
|
||||||
|
});
|
||||||
|
previewLayer(layerDescriptor);
|
||||||
|
};
|
||||||
|
|
||||||
|
return <TileServiceSelect onTileSelect={onSourceConfigChange} />;
|
||||||
|
},
|
||||||
|
title: sourceTitle,
|
||||||
|
};
|
|
@ -7,10 +7,8 @@
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { AbstractTMSSource } from '../tms_source';
|
import { AbstractTMSSource } from '../tms_source';
|
||||||
import { VectorTileLayer } from '../../vector_tile_layer';
|
|
||||||
|
|
||||||
import { getEMSClient } from '../../../meta';
|
import { getEMSClient } from '../../../meta';
|
||||||
import { TileServiceSelect } from './tile_service_select';
|
|
||||||
import { UpdateSourceEditor } from './update_source_editor';
|
import { UpdateSourceEditor } from './update_source_editor';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { getDataSourceLabel } from '../../../../common/i18n_getters';
|
import { getDataSourceLabel } from '../../../../common/i18n_getters';
|
||||||
|
@ -18,7 +16,7 @@ import { SOURCE_TYPES } from '../../../../common/constants';
|
||||||
import { getInjectedVarFunc, getUiSettings } from '../../../kibana_services';
|
import { getInjectedVarFunc, getUiSettings } from '../../../kibana_services';
|
||||||
import { registerSource } from '../source_registry';
|
import { registerSource } from '../source_registry';
|
||||||
|
|
||||||
const sourceTitle = i18n.translate('xpack.maps.source.emsTileTitle', {
|
export const sourceTitle = i18n.translate('xpack.maps.source.emsTileTitle', {
|
||||||
defaultMessage: 'EMS Basemaps',
|
defaultMessage: 'EMS Basemaps',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -84,20 +82,6 @@ export class EMSTMSSource extends AbstractTMSSource {
|
||||||
return tmsService;
|
return tmsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
_createDefaultLayerDescriptor(options) {
|
|
||||||
return VectorTileLayer.createDescriptor({
|
|
||||||
sourceDescriptor: this._descriptor,
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
createDefaultLayer(options) {
|
|
||||||
return new VectorTileLayer({
|
|
||||||
layerDescriptor: this._createDefaultLayerDescriptor(options),
|
|
||||||
source: this,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async getDisplayName() {
|
async getDisplayName() {
|
||||||
try {
|
try {
|
||||||
const emsTMSService = await this._getEMSTMSService();
|
const emsTMSService = await this._getEMSTMSService();
|
||||||
|
@ -150,20 +134,3 @@ registerSource({
|
||||||
ConstructorFunction: EMSTMSSource,
|
ConstructorFunction: EMSTMSSource,
|
||||||
type: SOURCE_TYPES.EMS_TMS,
|
type: SOURCE_TYPES.EMS_TMS,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const emsBaseMapLayerWizardConfig = {
|
|
||||||
description: i18n.translate('xpack.maps.source.emsTileDescription', {
|
|
||||||
defaultMessage: 'Tile map service from Elastic Maps Service',
|
|
||||||
}),
|
|
||||||
icon: 'emsApp',
|
|
||||||
renderWizard: ({ onPreviewSource, inspectorAdapters }) => {
|
|
||||||
const onSourceConfigChange = sourceConfig => {
|
|
||||||
const descriptor = EMSTMSSource.createDescriptor(sourceConfig);
|
|
||||||
const source = new EMSTMSSource(descriptor, inspectorAdapters);
|
|
||||||
onPreviewSource(source);
|
|
||||||
};
|
|
||||||
|
|
||||||
return <TileServiceSelect onTileSelect={onSourceConfigChange} />;
|
|
||||||
},
|
|
||||||
title: sourceTitle,
|
|
||||||
};
|
|
||||||
|
|
|
@ -4,4 +4,5 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { EMSTMSSource, emsBaseMapLayerWizardConfig } from './ems_tms_source';
|
export { emsBaseMapLayerWizardConfig } from './ems_base_map_layer_wizard';
|
||||||
|
export { EMSTMSSource } from './ems_tms_source';
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import React from 'react';
|
||||||
|
// @ts-ignore
|
||||||
|
import { CreateSourceEditor } from './create_source_editor';
|
||||||
|
// @ts-ignore
|
||||||
|
import { ESGeoGridSource, clustersTitle } from './es_geo_grid_source';
|
||||||
|
import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry';
|
||||||
|
import { VectorLayer } from '../../vector_layer';
|
||||||
|
import {
|
||||||
|
ESGeoGridSourceDescriptor,
|
||||||
|
ColorDynamicOptions,
|
||||||
|
SizeDynamicOptions,
|
||||||
|
} from '../../../../common/descriptor_types';
|
||||||
|
import { getDefaultDynamicProperties } from '../../styles/vector/vector_style_defaults';
|
||||||
|
import { VectorStyle } from '../../styles/vector/vector_style';
|
||||||
|
import {
|
||||||
|
COUNT_PROP_NAME,
|
||||||
|
COLOR_MAP_TYPE,
|
||||||
|
FIELD_ORIGIN,
|
||||||
|
RENDER_AS,
|
||||||
|
VECTOR_STYLES,
|
||||||
|
STYLE_TYPE,
|
||||||
|
} from '../../../../common/constants';
|
||||||
|
// @ts-ignore
|
||||||
|
import { COLOR_GRADIENTS } from '../../styles/color_utils';
|
||||||
|
|
||||||
|
export const clustersLayerWizardConfig: LayerWizard = {
|
||||||
|
description: i18n.translate('xpack.maps.source.esGridClustersDescription', {
|
||||||
|
defaultMessage: 'Geospatial data grouped in grids with metrics for each gridded cell',
|
||||||
|
}),
|
||||||
|
icon: 'logoElasticsearch',
|
||||||
|
renderWizard: ({ previewLayer }: RenderWizardArguments) => {
|
||||||
|
const onSourceConfigChange = (sourceConfig: Partial<ESGeoGridSourceDescriptor>) => {
|
||||||
|
if (!sourceConfig) {
|
||||||
|
previewLayer(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultDynamicProperties = getDefaultDynamicProperties();
|
||||||
|
const layerDescriptor = VectorLayer.createDescriptor({
|
||||||
|
sourceDescriptor: ESGeoGridSource.createDescriptor(sourceConfig),
|
||||||
|
style: VectorStyle.createDescriptor({
|
||||||
|
// @ts-ignore
|
||||||
|
[VECTOR_STYLES.FILL_COLOR]: {
|
||||||
|
type: STYLE_TYPE.DYNAMIC,
|
||||||
|
options: {
|
||||||
|
...(defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR]!
|
||||||
|
.options as ColorDynamicOptions),
|
||||||
|
field: {
|
||||||
|
name: COUNT_PROP_NAME,
|
||||||
|
origin: FIELD_ORIGIN.SOURCE,
|
||||||
|
},
|
||||||
|
color: COLOR_GRADIENTS[0].value,
|
||||||
|
type: COLOR_MAP_TYPE.ORDINAL,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[VECTOR_STYLES.LINE_COLOR]: {
|
||||||
|
type: STYLE_TYPE.STATIC,
|
||||||
|
options: {
|
||||||
|
color: '#FFF',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[VECTOR_STYLES.LINE_WIDTH]: {
|
||||||
|
type: STYLE_TYPE.STATIC,
|
||||||
|
options: {
|
||||||
|
size: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[VECTOR_STYLES.ICON_SIZE]: {
|
||||||
|
type: STYLE_TYPE.DYNAMIC,
|
||||||
|
options: {
|
||||||
|
...(defaultDynamicProperties[VECTOR_STYLES.ICON_SIZE]!.options as SizeDynamicOptions),
|
||||||
|
field: {
|
||||||
|
name: COUNT_PROP_NAME,
|
||||||
|
origin: FIELD_ORIGIN.SOURCE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[VECTOR_STYLES.LABEL_TEXT]: {
|
||||||
|
type: STYLE_TYPE.DYNAMIC,
|
||||||
|
options: {
|
||||||
|
...defaultDynamicProperties[VECTOR_STYLES.LABEL_TEXT]!.options,
|
||||||
|
field: {
|
||||||
|
name: COUNT_PROP_NAME,
|
||||||
|
origin: FIELD_ORIGIN.SOURCE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
previewLayer(layerDescriptor);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CreateSourceEditor
|
||||||
|
requestType={RENDER_AS.POINT}
|
||||||
|
onSourceConfigChange={onSourceConfigChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
title: clustersTitle,
|
||||||
|
};
|
|
@ -8,39 +8,27 @@ import React from 'react';
|
||||||
import uuid from 'uuid/v4';
|
import uuid from 'uuid/v4';
|
||||||
|
|
||||||
import { VECTOR_SHAPE_TYPES } from '../vector_feature_types';
|
import { VECTOR_SHAPE_TYPES } from '../vector_feature_types';
|
||||||
import { HeatmapLayer } from '../../heatmap_layer';
|
|
||||||
import { VectorLayer } from '../../vector_layer';
|
|
||||||
import { convertCompositeRespToGeoJson, convertRegularRespToGeoJson } from './convert_to_geojson';
|
import { convertCompositeRespToGeoJson, convertRegularRespToGeoJson } from './convert_to_geojson';
|
||||||
import { VectorStyle } from '../../styles/vector/vector_style';
|
|
||||||
import { getDefaultDynamicProperties } from '../../styles/vector/vector_style_defaults';
|
|
||||||
import { COLOR_GRADIENTS } from '../../styles/color_utils';
|
|
||||||
import { CreateSourceEditor } from './create_source_editor';
|
|
||||||
import { UpdateSourceEditor } from './update_source_editor';
|
import { UpdateSourceEditor } from './update_source_editor';
|
||||||
import {
|
import {
|
||||||
SOURCE_TYPES,
|
SOURCE_TYPES,
|
||||||
DEFAULT_MAX_BUCKETS_LIMIT,
|
DEFAULT_MAX_BUCKETS_LIMIT,
|
||||||
COUNT_PROP_NAME,
|
|
||||||
COLOR_MAP_TYPE,
|
|
||||||
RENDER_AS,
|
RENDER_AS,
|
||||||
GRID_RESOLUTION,
|
GRID_RESOLUTION,
|
||||||
VECTOR_STYLES,
|
|
||||||
FIELD_ORIGIN,
|
|
||||||
} from '../../../../common/constants';
|
} from '../../../../common/constants';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { getDataSourceLabel } from '../../../../common/i18n_getters';
|
import { getDataSourceLabel } from '../../../../common/i18n_getters';
|
||||||
import { AbstractESAggSource } from '../es_agg_source';
|
import { AbstractESAggSource } from '../es_agg_source';
|
||||||
import { DynamicStyleProperty } from '../../styles/vector/properties/dynamic_style_property';
|
|
||||||
import { StaticStyleProperty } from '../../styles/vector/properties/static_style_property';
|
|
||||||
import { DataRequestAbortError } from '../../util/data_request';
|
import { DataRequestAbortError } from '../../util/data_request';
|
||||||
import { registerSource } from '../source_registry';
|
import { registerSource } from '../source_registry';
|
||||||
|
|
||||||
export const MAX_GEOTILE_LEVEL = 29;
|
export const MAX_GEOTILE_LEVEL = 29;
|
||||||
|
|
||||||
const clustersTitle = i18n.translate('xpack.maps.source.esGridClustersTitle', {
|
export const clustersTitle = i18n.translate('xpack.maps.source.esGridClustersTitle', {
|
||||||
defaultMessage: 'Clusters and grids',
|
defaultMessage: 'Clusters and grids',
|
||||||
});
|
});
|
||||||
|
|
||||||
const heatmapTitle = i18n.translate('xpack.maps.source.esGridHeatmapTitle', {
|
export const heatmapTitle = i18n.translate('xpack.maps.source.esGridHeatmapTitle', {
|
||||||
defaultMessage: 'Heat map',
|
defaultMessage: 'Heat map',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -320,87 +308,6 @@ export class ESGeoGridSource extends AbstractESAggSource {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_createHeatmapLayerDescriptor(options) {
|
|
||||||
return HeatmapLayer.createDescriptor({
|
|
||||||
sourceDescriptor: this._descriptor,
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_createVectorLayerDescriptor(options) {
|
|
||||||
const descriptor = VectorLayer.createDescriptor({
|
|
||||||
sourceDescriptor: this._descriptor,
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
|
|
||||||
const defaultDynamicProperties = getDefaultDynamicProperties();
|
|
||||||
|
|
||||||
descriptor.style = VectorStyle.createDescriptor({
|
|
||||||
[VECTOR_STYLES.FILL_COLOR]: {
|
|
||||||
type: DynamicStyleProperty.type,
|
|
||||||
options: {
|
|
||||||
...defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR].options,
|
|
||||||
field: {
|
|
||||||
name: COUNT_PROP_NAME,
|
|
||||||
origin: FIELD_ORIGIN.SOURCE,
|
|
||||||
},
|
|
||||||
color: COLOR_GRADIENTS[0].value,
|
|
||||||
type: COLOR_MAP_TYPE.ORDINAL,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[VECTOR_STYLES.LINE_COLOR]: {
|
|
||||||
type: StaticStyleProperty.type,
|
|
||||||
options: {
|
|
||||||
color: '#FFF',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[VECTOR_STYLES.LINE_WIDTH]: {
|
|
||||||
type: StaticStyleProperty.type,
|
|
||||||
options: {
|
|
||||||
size: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[VECTOR_STYLES.ICON_SIZE]: {
|
|
||||||
type: DynamicStyleProperty.type,
|
|
||||||
options: {
|
|
||||||
...defaultDynamicProperties[VECTOR_STYLES.ICON_SIZE].options,
|
|
||||||
field: {
|
|
||||||
name: COUNT_PROP_NAME,
|
|
||||||
origin: FIELD_ORIGIN.SOURCE,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[VECTOR_STYLES.LABEL_TEXT]: {
|
|
||||||
type: DynamicStyleProperty.type,
|
|
||||||
options: {
|
|
||||||
...defaultDynamicProperties[VECTOR_STYLES.LABEL_TEXT].options,
|
|
||||||
field: {
|
|
||||||
name: COUNT_PROP_NAME,
|
|
||||||
origin: FIELD_ORIGIN.SOURCE,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return descriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
createDefaultLayer(options) {
|
|
||||||
if (this._descriptor.requestType === RENDER_AS.HEATMAP) {
|
|
||||||
return new HeatmapLayer({
|
|
||||||
layerDescriptor: this._createHeatmapLayerDescriptor(options),
|
|
||||||
source: this,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const layerDescriptor = this._createVectorLayerDescriptor(options);
|
|
||||||
const style = new VectorStyle(layerDescriptor.style, this);
|
|
||||||
return new VectorLayer({
|
|
||||||
layerDescriptor,
|
|
||||||
source: this,
|
|
||||||
style,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
canFormatFeatureProperties() {
|
canFormatFeatureProperties() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -422,57 +329,3 @@ registerSource({
|
||||||
ConstructorFunction: ESGeoGridSource,
|
ConstructorFunction: ESGeoGridSource,
|
||||||
type: SOURCE_TYPES.ES_GEO_GRID,
|
type: SOURCE_TYPES.ES_GEO_GRID,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const clustersLayerWizardConfig = {
|
|
||||||
description: i18n.translate('xpack.maps.source.esGridClustersDescription', {
|
|
||||||
defaultMessage: 'Geospatial data grouped in grids with metrics for each gridded cell',
|
|
||||||
}),
|
|
||||||
icon: 'logoElasticsearch',
|
|
||||||
renderWizard: ({ onPreviewSource, inspectorAdapters }) => {
|
|
||||||
const onSourceConfigChange = sourceConfig => {
|
|
||||||
if (!sourceConfig) {
|
|
||||||
onPreviewSource(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sourceDescriptor = ESGeoGridSource.createDescriptor(sourceConfig);
|
|
||||||
const source = new ESGeoGridSource(sourceDescriptor, inspectorAdapters);
|
|
||||||
onPreviewSource(source);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CreateSourceEditor
|
|
||||||
requestType={RENDER_AS.POINT}
|
|
||||||
onSourceConfigChange={onSourceConfigChange}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
title: clustersTitle,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const heatmapLayerWizardConfig = {
|
|
||||||
description: i18n.translate('xpack.maps.source.esGridHeatmapDescription', {
|
|
||||||
defaultMessage: 'Geospatial data grouped in grids to show density',
|
|
||||||
}),
|
|
||||||
icon: 'logoElasticsearch',
|
|
||||||
renderWizard: ({ onPreviewSource, inspectorAdapters }) => {
|
|
||||||
const onSourceConfigChange = sourceConfig => {
|
|
||||||
if (!sourceConfig) {
|
|
||||||
onPreviewSource(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sourceDescriptor = ESGeoGridSource.createDescriptor(sourceConfig);
|
|
||||||
const source = new ESGeoGridSource(sourceDescriptor, inspectorAdapters);
|
|
||||||
onPreviewSource(source);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CreateSourceEditor
|
|
||||||
requestType={RENDER_AS.HEATMAP}
|
|
||||||
onSourceConfigChange={onSourceConfigChange}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
title: heatmapTitle,
|
|
||||||
};
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import React from 'react';
|
||||||
|
// @ts-ignore
|
||||||
|
import { CreateSourceEditor } from './create_source_editor';
|
||||||
|
// @ts-ignore
|
||||||
|
import { ESGeoGridSource, heatmapTitle } from './es_geo_grid_source';
|
||||||
|
import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry';
|
||||||
|
// @ts-ignore
|
||||||
|
import { HeatmapLayer } from '../../heatmap_layer';
|
||||||
|
import { ESGeoGridSourceDescriptor } from '../../../../common/descriptor_types';
|
||||||
|
import { RENDER_AS } from '../../../../common/constants';
|
||||||
|
|
||||||
|
export const heatmapLayerWizardConfig: LayerWizard = {
|
||||||
|
description: i18n.translate('xpack.maps.source.esGridHeatmapDescription', {
|
||||||
|
defaultMessage: 'Geospatial data grouped in grids to show density',
|
||||||
|
}),
|
||||||
|
icon: 'logoElasticsearch',
|
||||||
|
renderWizard: ({ previewLayer }: RenderWizardArguments) => {
|
||||||
|
const onSourceConfigChange = (sourceConfig: Partial<ESGeoGridSourceDescriptor>) => {
|
||||||
|
if (!sourceConfig) {
|
||||||
|
previewLayer(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const layerDescriptor = HeatmapLayer.createDescriptor({
|
||||||
|
sourceDescriptor: ESGeoGridSource.createDescriptor(sourceConfig),
|
||||||
|
});
|
||||||
|
previewLayer(layerDescriptor);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CreateSourceEditor
|
||||||
|
requestType={RENDER_AS.HEATMAP}
|
||||||
|
onSourceConfigChange={onSourceConfigChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
title: heatmapTitle,
|
||||||
|
};
|
|
@ -4,8 +4,6 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export {
|
export { clustersLayerWizardConfig } from './clusters_layer_wizard';
|
||||||
ESGeoGridSource,
|
export { ESGeoGridSource } from './es_geo_grid_source';
|
||||||
clustersLayerWizardConfig,
|
export { heatmapLayerWizardConfig } from './heatmap_layer_wizard';
|
||||||
heatmapLayerWizardConfig,
|
|
||||||
} from './es_geo_grid_source';
|
|
||||||
|
|
|
@ -8,29 +8,18 @@ import React from 'react';
|
||||||
import uuid from 'uuid/v4';
|
import uuid from 'uuid/v4';
|
||||||
|
|
||||||
import { VECTOR_SHAPE_TYPES } from '../vector_feature_types';
|
import { VECTOR_SHAPE_TYPES } from '../vector_feature_types';
|
||||||
import { VectorLayer } from '../../vector_layer';
|
|
||||||
import { CreateSourceEditor } from './create_source_editor';
|
|
||||||
import { UpdateSourceEditor } from './update_source_editor';
|
import { UpdateSourceEditor } from './update_source_editor';
|
||||||
import { VectorStyle } from '../../styles/vector/vector_style';
|
|
||||||
import { getDefaultDynamicProperties } from '../../styles/vector/vector_style_defaults';
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import {
|
import { SOURCE_TYPES } from '../../../../common/constants';
|
||||||
FIELD_ORIGIN,
|
|
||||||
SOURCE_TYPES,
|
|
||||||
COUNT_PROP_NAME,
|
|
||||||
VECTOR_STYLES,
|
|
||||||
} from '../../../../common/constants';
|
|
||||||
import { getDataSourceLabel } from '../../../../common/i18n_getters';
|
import { getDataSourceLabel } from '../../../../common/i18n_getters';
|
||||||
import { convertToLines } from './convert_to_lines';
|
import { convertToLines } from './convert_to_lines';
|
||||||
import { AbstractESAggSource } from '../es_agg_source';
|
import { AbstractESAggSource } from '../es_agg_source';
|
||||||
import { DynamicStyleProperty } from '../../styles/vector/properties/dynamic_style_property';
|
|
||||||
import { COLOR_GRADIENTS } from '../../styles/color_utils';
|
|
||||||
import { indexPatterns } from '../../../../../../../src/plugins/data/public';
|
import { indexPatterns } from '../../../../../../../src/plugins/data/public';
|
||||||
import { registerSource } from '../source_registry';
|
import { registerSource } from '../source_registry';
|
||||||
|
|
||||||
const MAX_GEOTILE_LEVEL = 29;
|
const MAX_GEOTILE_LEVEL = 29;
|
||||||
|
|
||||||
const sourceTitle = i18n.translate('xpack.maps.source.pewPewTitle', {
|
export const sourceTitle = i18n.translate('xpack.maps.source.pewPewTitle', {
|
||||||
defaultMessage: 'Point to point',
|
defaultMessage: 'Point to point',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -109,43 +98,6 @@ export class ESPewPewSource extends AbstractESAggSource {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
createDefaultLayer(options) {
|
|
||||||
const defaultDynamicProperties = getDefaultDynamicProperties();
|
|
||||||
const styleDescriptor = VectorStyle.createDescriptor({
|
|
||||||
[VECTOR_STYLES.LINE_COLOR]: {
|
|
||||||
type: DynamicStyleProperty.type,
|
|
||||||
options: {
|
|
||||||
...defaultDynamicProperties[VECTOR_STYLES.LINE_COLOR].options,
|
|
||||||
field: {
|
|
||||||
name: COUNT_PROP_NAME,
|
|
||||||
origin: FIELD_ORIGIN.SOURCE,
|
|
||||||
},
|
|
||||||
color: COLOR_GRADIENTS[0].value,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[VECTOR_STYLES.LINE_WIDTH]: {
|
|
||||||
type: DynamicStyleProperty.type,
|
|
||||||
options: {
|
|
||||||
...defaultDynamicProperties[VECTOR_STYLES.LINE_WIDTH].options,
|
|
||||||
field: {
|
|
||||||
name: COUNT_PROP_NAME,
|
|
||||||
origin: FIELD_ORIGIN.SOURCE,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return new VectorLayer({
|
|
||||||
layerDescriptor: VectorLayer.createDescriptor({
|
|
||||||
...options,
|
|
||||||
sourceDescriptor: this._descriptor,
|
|
||||||
style: styleDescriptor,
|
|
||||||
}),
|
|
||||||
source: this,
|
|
||||||
style: new VectorStyle(styleDescriptor, this),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getGeoGridPrecision(zoom) {
|
getGeoGridPrecision(zoom) {
|
||||||
const targetGeotileLevel = Math.ceil(zoom) + 2;
|
const targetGeotileLevel = Math.ceil(zoom) + 2;
|
||||||
return Math.min(targetGeotileLevel, MAX_GEOTILE_LEVEL);
|
return Math.min(targetGeotileLevel, MAX_GEOTILE_LEVEL);
|
||||||
|
@ -234,25 +186,3 @@ registerSource({
|
||||||
ConstructorFunction: ESPewPewSource,
|
ConstructorFunction: ESPewPewSource,
|
||||||
type: SOURCE_TYPES.ES_PEW_PEW,
|
type: SOURCE_TYPES.ES_PEW_PEW,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const point2PointLayerWizardConfig = {
|
|
||||||
description: i18n.translate('xpack.maps.source.pewPewDescription', {
|
|
||||||
defaultMessage: 'Aggregated data paths between the source and destination',
|
|
||||||
}),
|
|
||||||
icon: 'logoElasticsearch',
|
|
||||||
renderWizard: ({ onPreviewSource, inspectorAdapters }) => {
|
|
||||||
const onSourceConfigChange = sourceConfig => {
|
|
||||||
if (!sourceConfig) {
|
|
||||||
onPreviewSource(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sourceDescriptor = ESPewPewSource.createDescriptor(sourceConfig);
|
|
||||||
const source = new ESPewPewSource(sourceDescriptor, inspectorAdapters);
|
|
||||||
onPreviewSource(source);
|
|
||||||
};
|
|
||||||
|
|
||||||
return <CreateSourceEditor onSourceConfigChange={onSourceConfigChange} />;
|
|
||||||
},
|
|
||||||
title: sourceTitle,
|
|
||||||
};
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export { ESPewPewSource } from './es_pew_pew_source';
|
||||||
|
export { point2PointLayerWizardConfig } from './point_2_point_layer_wizard';
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import { getDefaultDynamicProperties } from '../../styles/vector/vector_style_defaults';
|
||||||
|
import { VectorLayer } from '../../vector_layer';
|
||||||
|
// @ts-ignore
|
||||||
|
import { ESPewPewSource, sourceTitle } from './es_pew_pew_source';
|
||||||
|
import { VectorStyle } from '../../styles/vector/vector_style';
|
||||||
|
import {
|
||||||
|
FIELD_ORIGIN,
|
||||||
|
COUNT_PROP_NAME,
|
||||||
|
VECTOR_STYLES,
|
||||||
|
STYLE_TYPE,
|
||||||
|
} from '../../../../common/constants';
|
||||||
|
// @ts-ignore
|
||||||
|
import { COLOR_GRADIENTS } from '../../styles/color_utils';
|
||||||
|
// @ts-ignore
|
||||||
|
import { CreateSourceEditor } from './create_source_editor';
|
||||||
|
import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry';
|
||||||
|
import { ColorDynamicOptions, SizeDynamicOptions } from '../../../../common/descriptor_types';
|
||||||
|
|
||||||
|
export const point2PointLayerWizardConfig: LayerWizard = {
|
||||||
|
description: i18n.translate('xpack.maps.source.pewPewDescription', {
|
||||||
|
defaultMessage: 'Aggregated data paths between the source and destination',
|
||||||
|
}),
|
||||||
|
icon: 'logoElasticsearch',
|
||||||
|
renderWizard: ({ previewLayer }: RenderWizardArguments) => {
|
||||||
|
const onSourceConfigChange = (sourceConfig: unknown) => {
|
||||||
|
if (!sourceConfig) {
|
||||||
|
previewLayer(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultDynamicProperties = getDefaultDynamicProperties();
|
||||||
|
const layerDescriptor = VectorLayer.createDescriptor({
|
||||||
|
sourceDescriptor: ESPewPewSource.createDescriptor(sourceConfig),
|
||||||
|
style: VectorStyle.createDescriptor({
|
||||||
|
[VECTOR_STYLES.LINE_COLOR]: {
|
||||||
|
type: STYLE_TYPE.DYNAMIC,
|
||||||
|
options: {
|
||||||
|
...(defaultDynamicProperties[VECTOR_STYLES.LINE_COLOR]!
|
||||||
|
.options as ColorDynamicOptions),
|
||||||
|
field: {
|
||||||
|
name: COUNT_PROP_NAME,
|
||||||
|
origin: FIELD_ORIGIN.SOURCE,
|
||||||
|
},
|
||||||
|
color: COLOR_GRADIENTS[0].value,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[VECTOR_STYLES.LINE_WIDTH]: {
|
||||||
|
type: STYLE_TYPE.DYNAMIC,
|
||||||
|
options: {
|
||||||
|
...(defaultDynamicProperties[VECTOR_STYLES.LINE_WIDTH]!
|
||||||
|
.options as SizeDynamicOptions),
|
||||||
|
field: {
|
||||||
|
name: COUNT_PROP_NAME,
|
||||||
|
origin: FIELD_ORIGIN.SOURCE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
previewLayer(layerDescriptor);
|
||||||
|
};
|
||||||
|
|
||||||
|
return <CreateSourceEditor onSourceConfigChange={onSourceConfigChange} />;
|
||||||
|
},
|
||||||
|
title: sourceTitle,
|
||||||
|
};
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import React from 'react';
|
||||||
|
// @ts-ignore
|
||||||
|
import { CreateSourceEditor } from './create_source_editor';
|
||||||
|
import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry';
|
||||||
|
// @ts-ignore
|
||||||
|
import { ESSearchSource, sourceTitle } from './es_search_source';
|
||||||
|
import { BlendedVectorLayer } from '../../blended_vector_layer';
|
||||||
|
import { VectorLayer } from '../../vector_layer';
|
||||||
|
import { SCALING_TYPES } from '../../../../common/constants';
|
||||||
|
|
||||||
|
export function createDefaultLayerDescriptor(sourceConfig: unknown, mapColors: string[]) {
|
||||||
|
const sourceDescriptor = ESSearchSource.createDescriptor(sourceConfig);
|
||||||
|
|
||||||
|
return sourceDescriptor.scalingType === SCALING_TYPES.CLUSTERS
|
||||||
|
? BlendedVectorLayer.createDescriptor({ sourceDescriptor }, mapColors)
|
||||||
|
: VectorLayer.createDescriptor({ sourceDescriptor }, mapColors);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const esDocumentsLayerWizardConfig: LayerWizard = {
|
||||||
|
description: i18n.translate('xpack.maps.source.esSearchDescription', {
|
||||||
|
defaultMessage: 'Vector data from a Kibana index pattern',
|
||||||
|
}),
|
||||||
|
icon: 'logoElasticsearch',
|
||||||
|
renderWizard: ({ previewLayer, mapColors }: RenderWizardArguments) => {
|
||||||
|
const onSourceConfigChange = (sourceConfig: unknown) => {
|
||||||
|
if (!sourceConfig) {
|
||||||
|
previewLayer(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
previewLayer(createDefaultLayerDescriptor(sourceConfig, mapColors));
|
||||||
|
};
|
||||||
|
return <CreateSourceEditor onSourceConfigChange={onSourceConfigChange} />;
|
||||||
|
},
|
||||||
|
title: sourceTitle,
|
||||||
|
};
|
|
@ -8,6 +8,8 @@ import { AbstractESSource } from '../es_source';
|
||||||
import { ESSearchSourceDescriptor } from '../../../../common/descriptor_types';
|
import { ESSearchSourceDescriptor } from '../../../../common/descriptor_types';
|
||||||
|
|
||||||
export class ESSearchSource extends AbstractESSource {
|
export class ESSearchSource extends AbstractESSource {
|
||||||
|
static createDescriptor(sourceConfig: unknown): ESSearchSourceDescriptor;
|
||||||
|
|
||||||
constructor(sourceDescriptor: Partial<ESSearchSourceDescriptor>, inspectorAdapters: unknown);
|
constructor(sourceDescriptor: Partial<ESSearchSourceDescriptor>, inspectorAdapters: unknown);
|
||||||
getFieldNames(): string[];
|
getFieldNames(): string[];
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,11 @@
|
||||||
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import uuid from 'uuid/v4';
|
|
||||||
|
|
||||||
import { VECTOR_SHAPE_TYPES } from '../vector_feature_types';
|
import { VECTOR_SHAPE_TYPES } from '../vector_feature_types';
|
||||||
import { AbstractESSource } from '../es_source';
|
import { AbstractESSource } from '../es_source';
|
||||||
import { getSearchService } from '../../../kibana_services';
|
import { getSearchService } from '../../../kibana_services';
|
||||||
import { VectorStyle } from '../../styles/vector/vector_style';
|
|
||||||
import { VectorLayer } from '../../vector_layer';
|
|
||||||
import { hitsToGeoJson } from '../../../elasticsearch_geo_utils';
|
import { hitsToGeoJson } from '../../../elasticsearch_geo_utils';
|
||||||
import { CreateSourceEditor } from './create_source_editor';
|
|
||||||
import { UpdateSourceEditor } from './update_source_editor';
|
import { UpdateSourceEditor } from './update_source_editor';
|
||||||
import {
|
import {
|
||||||
SOURCE_TYPES,
|
SOURCE_TYPES,
|
||||||
|
@ -27,14 +23,14 @@ import { i18n } from '@kbn/i18n';
|
||||||
import { getDataSourceLabel } from '../../../../common/i18n_getters';
|
import { getDataSourceLabel } from '../../../../common/i18n_getters';
|
||||||
import { getSourceFields } from '../../../index_pattern_util';
|
import { getSourceFields } from '../../../index_pattern_util';
|
||||||
import { loadIndexSettings } from './load_index_settings';
|
import { loadIndexSettings } from './load_index_settings';
|
||||||
import { BlendedVectorLayer } from '../../blended_vector_layer';
|
import uuid from 'uuid/v4';
|
||||||
|
|
||||||
import { DEFAULT_FILTER_BY_MAP_BOUNDS } from './constants';
|
import { DEFAULT_FILTER_BY_MAP_BOUNDS } from './constants';
|
||||||
import { ESDocField } from '../../fields/es_doc_field';
|
import { ESDocField } from '../../fields/es_doc_field';
|
||||||
import { getField, addFieldToDSL } from '../../util/es_agg_utils';
|
import { getField, addFieldToDSL } from '../../util/es_agg_utils';
|
||||||
import { registerSource } from '../source_registry';
|
import { registerSource } from '../source_registry';
|
||||||
|
|
||||||
const sourceTitle = i18n.translate('xpack.maps.source.esSearchTitle', {
|
export const sourceTitle = i18n.translate('xpack.maps.source.esSearchTitle', {
|
||||||
defaultMessage: 'Documents',
|
defaultMessage: 'Documents',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -71,56 +67,31 @@ function getDocValueAndSourceFields(indexPattern, fieldNames) {
|
||||||
export class ESSearchSource extends AbstractESSource {
|
export class ESSearchSource extends AbstractESSource {
|
||||||
static type = SOURCE_TYPES.ES_SEARCH;
|
static type = SOURCE_TYPES.ES_SEARCH;
|
||||||
|
|
||||||
|
static createDescriptor(descriptor) {
|
||||||
|
return {
|
||||||
|
...descriptor,
|
||||||
|
id: descriptor.id ? descriptor.id : uuid(),
|
||||||
|
type: ESSearchSource.type,
|
||||||
|
indexPatternId: descriptor.indexPatternId,
|
||||||
|
geoField: descriptor.geoField,
|
||||||
|
filterByMapBounds: _.get(descriptor, 'filterByMapBounds', DEFAULT_FILTER_BY_MAP_BOUNDS),
|
||||||
|
tooltipProperties: _.get(descriptor, 'tooltipProperties', []),
|
||||||
|
sortField: _.get(descriptor, 'sortField', ''),
|
||||||
|
sortOrder: _.get(descriptor, 'sortOrder', SORT_ORDER.DESC),
|
||||||
|
scalingType: _.get(descriptor, 'scalingType', SCALING_TYPES.LIMIT),
|
||||||
|
topHitsSplitField: descriptor.topHitsSplitField,
|
||||||
|
topHitsSize: _.get(descriptor, 'topHitsSize', 1),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
constructor(descriptor, inspectorAdapters) {
|
constructor(descriptor, inspectorAdapters) {
|
||||||
super(
|
super(ESSearchSource.createDescriptor(descriptor), inspectorAdapters);
|
||||||
{
|
|
||||||
...descriptor,
|
|
||||||
id: descriptor.id,
|
|
||||||
type: ESSearchSource.type,
|
|
||||||
indexPatternId: descriptor.indexPatternId,
|
|
||||||
geoField: descriptor.geoField,
|
|
||||||
filterByMapBounds: _.get(descriptor, 'filterByMapBounds', DEFAULT_FILTER_BY_MAP_BOUNDS),
|
|
||||||
tooltipProperties: _.get(descriptor, 'tooltipProperties', []),
|
|
||||||
sortField: _.get(descriptor, 'sortField', ''),
|
|
||||||
sortOrder: _.get(descriptor, 'sortOrder', SORT_ORDER.DESC),
|
|
||||||
scalingType: _.get(descriptor, 'scalingType', SCALING_TYPES.LIMIT),
|
|
||||||
topHitsSplitField: descriptor.topHitsSplitField,
|
|
||||||
topHitsSize: _.get(descriptor, 'topHitsSize', 1),
|
|
||||||
},
|
|
||||||
inspectorAdapters
|
|
||||||
);
|
|
||||||
|
|
||||||
this._tooltipFields = this._descriptor.tooltipProperties.map(property =>
|
this._tooltipFields = this._descriptor.tooltipProperties.map(property =>
|
||||||
this.createField({ fieldName: property })
|
this.createField({ fieldName: property })
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
createDefaultLayer(options, mapColors) {
|
|
||||||
if (this._descriptor.scalingType === SCALING_TYPES.CLUSTERS) {
|
|
||||||
const layerDescriptor = BlendedVectorLayer.createDescriptor(
|
|
||||||
{
|
|
||||||
sourceDescriptor: this._descriptor,
|
|
||||||
...options,
|
|
||||||
},
|
|
||||||
mapColors
|
|
||||||
);
|
|
||||||
const style = new VectorStyle(layerDescriptor.style, this);
|
|
||||||
return new BlendedVectorLayer({
|
|
||||||
layerDescriptor: layerDescriptor,
|
|
||||||
source: this,
|
|
||||||
style,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const layerDescriptor = this._createDefaultLayerDescriptor(options, mapColors);
|
|
||||||
const style = new VectorStyle(layerDescriptor.style, this);
|
|
||||||
return new VectorLayer({
|
|
||||||
layerDescriptor: layerDescriptor,
|
|
||||||
source: this,
|
|
||||||
style,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
createField({ fieldName }) {
|
createField({ fieldName }) {
|
||||||
return new ESDocField({
|
return new ESDocField({
|
||||||
fieldName,
|
fieldName,
|
||||||
|
@ -586,29 +557,3 @@ registerSource({
|
||||||
ConstructorFunction: ESSearchSource,
|
ConstructorFunction: ESSearchSource,
|
||||||
type: SOURCE_TYPES.ES_SEARCH,
|
type: SOURCE_TYPES.ES_SEARCH,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const esDocumentsLayerWizardConfig = {
|
|
||||||
description: i18n.translate('xpack.maps.source.esSearchDescription', {
|
|
||||||
defaultMessage: 'Vector data from a Kibana index pattern',
|
|
||||||
}),
|
|
||||||
icon: 'logoElasticsearch',
|
|
||||||
renderWizard: ({ onPreviewSource, inspectorAdapters }) => {
|
|
||||||
const onSourceConfigChange = sourceConfig => {
|
|
||||||
if (!sourceConfig) {
|
|
||||||
onPreviewSource(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const source = new ESSearchSource(
|
|
||||||
{
|
|
||||||
id: uuid(),
|
|
||||||
...sourceConfig,
|
|
||||||
},
|
|
||||||
inspectorAdapters
|
|
||||||
);
|
|
||||||
onPreviewSource(source);
|
|
||||||
};
|
|
||||||
return <CreateSourceEditor onSourceConfigChange={onSourceConfigChange} />;
|
|
||||||
},
|
|
||||||
title: sourceTitle,
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,33 +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;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
jest.mock('ui/new_platform');
|
|
||||||
jest.mock('../../../kibana_services');
|
|
||||||
|
|
||||||
import { ESSearchSource } from './es_search_source';
|
|
||||||
import { VectorLayer } from '../../vector_layer';
|
|
||||||
import { SCALING_TYPES, SOURCE_TYPES } from '../../../../common/constants';
|
|
||||||
import { ESSearchSourceDescriptor } from '../../../../common/descriptor_types';
|
|
||||||
|
|
||||||
const descriptor: ESSearchSourceDescriptor = {
|
|
||||||
type: SOURCE_TYPES.ES_SEARCH,
|
|
||||||
id: '1234',
|
|
||||||
indexPatternId: 'myIndexPattern',
|
|
||||||
geoField: 'myLocation',
|
|
||||||
scalingType: SCALING_TYPES.LIMIT,
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('ES Search Source', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
require('../../../kibana_services').getUiSettings = () => ({
|
|
||||||
get: jest.fn(),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('should create a vector layer', () => {
|
|
||||||
const source = new ESSearchSource(descriptor, null);
|
|
||||||
const layer = source.createDefaultLayer();
|
|
||||||
expect(layer instanceof VectorLayer).toEqual(true);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -4,4 +4,8 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { ESSearchSource, esDocumentsLayerWizardConfig } from './es_search_source';
|
export { ESSearchSource } from './es_search_source';
|
||||||
|
export {
|
||||||
|
createDefaultLayerDescriptor,
|
||||||
|
esDocumentsLayerWizardConfig,
|
||||||
|
} from './es_documents_layer_wizard';
|
||||||
|
|
|
@ -4,4 +4,5 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { KibanaRegionmapSource, kibanaRegionMapLayerWizardConfig } from './kibana_regionmap_source';
|
export { kibanaRegionMapLayerWizardConfig } from './kibana_regionmap_layer_wizard';
|
||||||
|
export { KibanaRegionmapSource } from './kibana_regionmap_source';
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry';
|
||||||
|
// @ts-ignore
|
||||||
|
import { KibanaRegionmapSource, sourceTitle } from './kibana_regionmap_source';
|
||||||
|
import { VectorLayer } from '../../vector_layer';
|
||||||
|
// @ts-ignore
|
||||||
|
import { CreateSourceEditor } from './create_source_editor';
|
||||||
|
|
||||||
|
export const kibanaRegionMapLayerWizardConfig: LayerWizard = {
|
||||||
|
description: i18n.translate('xpack.maps.source.kbnRegionMapDescription', {
|
||||||
|
defaultMessage: 'Vector data from hosted GeoJSON configured in kibana.yml',
|
||||||
|
}),
|
||||||
|
icon: 'logoKibana',
|
||||||
|
renderWizard: ({ previewLayer, mapColors }: RenderWizardArguments) => {
|
||||||
|
const onSourceConfigChange = (sourceConfig: unknown) => {
|
||||||
|
const sourceDescriptor = KibanaRegionmapSource.createDescriptor(sourceConfig);
|
||||||
|
const layerDescriptor = VectorLayer.createDescriptor({ sourceDescriptor }, mapColors);
|
||||||
|
previewLayer(layerDescriptor);
|
||||||
|
};
|
||||||
|
|
||||||
|
return <CreateSourceEditor onSourceConfigChange={onSourceConfigChange} />;
|
||||||
|
},
|
||||||
|
title: sourceTitle,
|
||||||
|
};
|
|
@ -5,8 +5,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { AbstractVectorSource } from '../vector_source';
|
import { AbstractVectorSource } from '../vector_source';
|
||||||
import React from 'react';
|
|
||||||
import { CreateSourceEditor } from './create_source_editor';
|
|
||||||
import { getKibanaRegionList } from '../../../meta';
|
import { getKibanaRegionList } from '../../../meta';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { getDataSourceLabel } from '../../../../common/i18n_getters';
|
import { getDataSourceLabel } from '../../../../common/i18n_getters';
|
||||||
|
@ -14,7 +12,7 @@ import { FIELD_ORIGIN, SOURCE_TYPES } from '../../../../common/constants';
|
||||||
import { KibanaRegionField } from '../../fields/kibana_region_field';
|
import { KibanaRegionField } from '../../fields/kibana_region_field';
|
||||||
import { registerSource } from '../source_registry';
|
import { registerSource } from '../source_registry';
|
||||||
|
|
||||||
const sourceTitle = i18n.translate('xpack.maps.source.kbnRegionMapTitle', {
|
export const sourceTitle = i18n.translate('xpack.maps.source.kbnRegionMapTitle', {
|
||||||
defaultMessage: 'Configured GeoJSON',
|
defaultMessage: 'Configured GeoJSON',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -101,20 +99,3 @@ registerSource({
|
||||||
ConstructorFunction: KibanaRegionmapSource,
|
ConstructorFunction: KibanaRegionmapSource,
|
||||||
type: SOURCE_TYPES.REGIONMAP_FILE,
|
type: SOURCE_TYPES.REGIONMAP_FILE,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const kibanaRegionMapLayerWizardConfig = {
|
|
||||||
description: i18n.translate('xpack.maps.source.kbnRegionMapDescription', {
|
|
||||||
defaultMessage: 'Vector data from hosted GeoJSON configured in kibana.yml',
|
|
||||||
}),
|
|
||||||
icon: 'logoKibana',
|
|
||||||
renderWizard: ({ onPreviewSource, inspectorAdapters }) => {
|
|
||||||
const onSourceConfigChange = sourceConfig => {
|
|
||||||
const sourceDescriptor = KibanaRegionmapSource.createDescriptor(sourceConfig);
|
|
||||||
const source = new KibanaRegionmapSource(sourceDescriptor, inspectorAdapters);
|
|
||||||
onPreviewSource(source);
|
|
||||||
};
|
|
||||||
|
|
||||||
return <CreateSourceEditor onSourceConfigChange={onSourceConfigChange} />;
|
|
||||||
},
|
|
||||||
title: sourceTitle,
|
|
||||||
};
|
|
||||||
|
|
|
@ -4,4 +4,5 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { KibanaTilemapSource, kibanaBasemapLayerWizardConfig } from './kibana_tilemap_source';
|
export { kibanaBasemapLayerWizardConfig } from './kibana_base_map_layer_wizard';
|
||||||
|
export { KibanaTilemapSource } from './kibana_tilemap_source';
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry';
|
||||||
|
// @ts-ignore
|
||||||
|
import { CreateSourceEditor } from './create_source_editor';
|
||||||
|
// @ts-ignore
|
||||||
|
import { KibanaTilemapSource, sourceTitle } from './kibana_tilemap_source';
|
||||||
|
import { TileLayer } from '../../tile_layer';
|
||||||
|
|
||||||
|
export const kibanaBasemapLayerWizardConfig: LayerWizard = {
|
||||||
|
description: i18n.translate('xpack.maps.source.kbnTMSDescription', {
|
||||||
|
defaultMessage: 'Tile map service configured in kibana.yml',
|
||||||
|
}),
|
||||||
|
icon: 'logoKibana',
|
||||||
|
renderWizard: ({ previewLayer }: RenderWizardArguments) => {
|
||||||
|
const onSourceConfigChange = () => {
|
||||||
|
const layerDescriptor = TileLayer.createDescriptor({
|
||||||
|
sourceDescriptor: KibanaTilemapSource.createDescriptor(),
|
||||||
|
});
|
||||||
|
previewLayer(layerDescriptor);
|
||||||
|
};
|
||||||
|
return <CreateSourceEditor onSourceConfigChange={onSourceConfigChange} />;
|
||||||
|
},
|
||||||
|
title: sourceTitle,
|
||||||
|
};
|
|
@ -3,10 +3,8 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
|
||||||
import { AbstractTMSSource } from '../tms_source';
|
import { AbstractTMSSource } from '../tms_source';
|
||||||
import { TileLayer } from '../../tile_layer';
|
|
||||||
import { CreateSourceEditor } from './create_source_editor';
|
|
||||||
import { getKibanaTileMap } from '../../../meta';
|
import { getKibanaTileMap } from '../../../meta';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { getDataSourceLabel } from '../../../../common/i18n_getters';
|
import { getDataSourceLabel } from '../../../../common/i18n_getters';
|
||||||
|
@ -14,7 +12,7 @@ import _ from 'lodash';
|
||||||
import { SOURCE_TYPES } from '../../../../common/constants';
|
import { SOURCE_TYPES } from '../../../../common/constants';
|
||||||
import { registerSource } from '../source_registry';
|
import { registerSource } from '../source_registry';
|
||||||
|
|
||||||
const sourceTitle = i18n.translate('xpack.maps.source.kbnTMSTitle', {
|
export const sourceTitle = i18n.translate('xpack.maps.source.kbnTMSTitle', {
|
||||||
defaultMessage: 'Configured Tile Map Service',
|
defaultMessage: 'Configured Tile Map Service',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -42,20 +40,6 @@ export class KibanaTilemapSource extends AbstractTMSSource {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
_createDefaultLayerDescriptor(options) {
|
|
||||||
return TileLayer.createDescriptor({
|
|
||||||
sourceDescriptor: this._descriptor,
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
createDefaultLayer(options) {
|
|
||||||
return new TileLayer({
|
|
||||||
layerDescriptor: this._createDefaultLayerDescriptor(options),
|
|
||||||
source: this,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async getUrlTemplate() {
|
async getUrlTemplate() {
|
||||||
const tilemap = getKibanaTileMap();
|
const tilemap = getKibanaTileMap();
|
||||||
if (!tilemap.url) {
|
if (!tilemap.url) {
|
||||||
|
@ -88,19 +72,3 @@ registerSource({
|
||||||
ConstructorFunction: KibanaTilemapSource,
|
ConstructorFunction: KibanaTilemapSource,
|
||||||
type: SOURCE_TYPES.KIBANA_TILEMAP,
|
type: SOURCE_TYPES.KIBANA_TILEMAP,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const kibanaBasemapLayerWizardConfig = {
|
|
||||||
description: i18n.translate('xpack.maps.source.kbnTMSDescription', {
|
|
||||||
defaultMessage: 'Tile map service configured in kibana.yml',
|
|
||||||
}),
|
|
||||||
icon: 'logoKibana',
|
|
||||||
renderWizard: ({ onPreviewSource, inspectorAdapters }) => {
|
|
||||||
const onSourceConfigChange = () => {
|
|
||||||
const sourceDescriptor = KibanaTilemapSource.createDescriptor();
|
|
||||||
const source = new KibanaTilemapSource(sourceDescriptor, inspectorAdapters);
|
|
||||||
onPreviewSource(source);
|
|
||||||
};
|
|
||||||
return <CreateSourceEditor onSourceConfigChange={onSourceConfigChange} />;
|
|
||||||
},
|
|
||||||
title: sourceTitle,
|
|
||||||
};
|
|
||||||
|
|
|
@ -12,30 +12,20 @@ import {
|
||||||
} from './mvt_single_layer_vector_source_editor';
|
} from './mvt_single_layer_vector_source_editor';
|
||||||
import { MVTSingleLayerVectorSource, sourceTitle } from './mvt_single_layer_vector_source';
|
import { MVTSingleLayerVectorSource, sourceTitle } from './mvt_single_layer_vector_source';
|
||||||
import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry';
|
import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry';
|
||||||
import { SOURCE_TYPES } from '../../../../common/constants';
|
import { TiledVectorLayer } from '../../tiled_vector_layer';
|
||||||
|
|
||||||
export const mvtVectorSourceWizardConfig: LayerWizard = {
|
export const mvtVectorSourceWizardConfig: LayerWizard = {
|
||||||
description: i18n.translate('xpack.maps.source.mvtVectorSourceWizard', {
|
description: i18n.translate('xpack.maps.source.mvtVectorSourceWizard', {
|
||||||
defaultMessage: 'Vector source wizard',
|
defaultMessage: 'Vector source wizard',
|
||||||
}),
|
}),
|
||||||
icon: 'grid',
|
icon: 'grid',
|
||||||
renderWizard: ({ onPreviewSource, inspectorAdapters }: RenderWizardArguments) => {
|
renderWizard: ({ previewLayer, mapColors }: RenderWizardArguments) => {
|
||||||
const onSourceConfigChange = ({
|
const onSourceConfigChange = (sourceConfig: MVTSingleLayerVectorSourceConfig) => {
|
||||||
urlTemplate,
|
const sourceDescriptor = MVTSingleLayerVectorSource.createDescriptor(sourceConfig);
|
||||||
layerName,
|
const layerDescriptor = TiledVectorLayer.createDescriptor({ sourceDescriptor }, mapColors);
|
||||||
minSourceZoom,
|
previewLayer(layerDescriptor);
|
||||||
maxSourceZoom,
|
|
||||||
}: MVTSingleLayerVectorSourceConfig) => {
|
|
||||||
const sourceDescriptor = MVTSingleLayerVectorSource.createDescriptor({
|
|
||||||
urlTemplate,
|
|
||||||
layerName,
|
|
||||||
minSourceZoom,
|
|
||||||
maxSourceZoom,
|
|
||||||
type: SOURCE_TYPES.MVT_SINGLE_LAYER,
|
|
||||||
});
|
|
||||||
const source = new MVTSingleLayerVectorSource(sourceDescriptor, inspectorAdapters);
|
|
||||||
onPreviewSource(source);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return <MVTSingleLayerVectorSourceEditor onSourceConfigChange={onSourceConfigChange} />;
|
return <MVTSingleLayerVectorSourceEditor onSourceConfigChange={onSourceConfigChange} />;
|
||||||
},
|
},
|
||||||
title: sourceTitle,
|
title: sourceTitle,
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import uuid from 'uuid/v4';
|
import uuid from 'uuid/v4';
|
||||||
import { AbstractSource, ImmutableSourceProperty } from '../source';
|
import { AbstractSource, ImmutableSourceProperty } from '../source';
|
||||||
import { TiledVectorLayer } from '../../tiled_vector_layer';
|
|
||||||
import { GeoJsonWithMeta, ITiledSingleLayerVectorSource } from '../vector_source';
|
import { GeoJsonWithMeta, ITiledSingleLayerVectorSource } from '../vector_source';
|
||||||
import { MAX_ZOOM, MIN_ZOOM, SOURCE_TYPES } from '../../../../common/constants';
|
import { MAX_ZOOM, MIN_ZOOM, SOURCE_TYPES } from '../../../../common/constants';
|
||||||
import { VECTOR_SHAPE_TYPES } from '../vector_feature_types';
|
import { VECTOR_SHAPE_TYPES } from '../vector_feature_types';
|
||||||
|
@ -17,11 +16,10 @@ import { getDataSourceLabel, getUrlLabel } from '../../../../common/i18n_getters
|
||||||
import {
|
import {
|
||||||
MapExtent,
|
MapExtent,
|
||||||
TiledSingleLayerVectorSourceDescriptor,
|
TiledSingleLayerVectorSourceDescriptor,
|
||||||
VectorLayerDescriptor,
|
|
||||||
VectorSourceRequestMeta,
|
VectorSourceRequestMeta,
|
||||||
VectorSourceSyncMeta,
|
VectorSourceSyncMeta,
|
||||||
} from '../../../../common/descriptor_types';
|
} from '../../../../common/descriptor_types';
|
||||||
import { VectorLayerArguments } from '../../vector_layer';
|
import { MVTSingleLayerVectorSourceConfig } from './mvt_single_layer_vector_source_editor';
|
||||||
|
|
||||||
export const sourceTitle = i18n.translate(
|
export const sourceTitle = i18n.translate(
|
||||||
'xpack.maps.source.MVTSingleLayerVectorSource.sourceTitle',
|
'xpack.maps.source.MVTSingleLayerVectorSource.sourceTitle',
|
||||||
|
@ -37,7 +35,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource
|
||||||
layerName,
|
layerName,
|
||||||
minSourceZoom,
|
minSourceZoom,
|
||||||
maxSourceZoom,
|
maxSourceZoom,
|
||||||
}: TiledSingleLayerVectorSourceDescriptor) {
|
}: MVTSingleLayerVectorSourceConfig) {
|
||||||
return {
|
return {
|
||||||
type: SOURCE_TYPES.MVT_SINGLE_LAYER,
|
type: SOURCE_TYPES.MVT_SINGLE_LAYER,
|
||||||
id: uuid(),
|
id: uuid(),
|
||||||
|
@ -66,22 +64,6 @@ export class MVTSingleLayerVectorSource extends AbstractSource
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
createDefaultLayer(options?: Partial<VectorLayerDescriptor>): TiledVectorLayer {
|
|
||||||
const layerDescriptor: Partial<VectorLayerDescriptor> = {
|
|
||||||
sourceDescriptor: this._descriptor,
|
|
||||||
...options,
|
|
||||||
};
|
|
||||||
const normalizedLayerDescriptor: VectorLayerDescriptor = TiledVectorLayer.createDescriptor(
|
|
||||||
layerDescriptor,
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
const vectorLayerArguments: VectorLayerArguments = {
|
|
||||||
layerDescriptor: normalizedLayerDescriptor,
|
|
||||||
source: this,
|
|
||||||
};
|
|
||||||
return new TiledVectorLayer(vectorLayerArguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
getGeoJsonWithMeta(
|
getGeoJsonWithMeta(
|
||||||
layerName: 'string',
|
layerName: 'string',
|
||||||
searchFilters: unknown[],
|
searchFilters: unknown[],
|
||||||
|
|
|
@ -13,8 +13,7 @@ import { Adapters } from 'src/plugins/inspector/public';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { copyPersistentState } from '../../reducers/util';
|
import { copyPersistentState } from '../../reducers/util';
|
||||||
|
|
||||||
import { LayerDescriptor, SourceDescriptor } from '../../../common/descriptor_types';
|
import { SourceDescriptor } from '../../../common/descriptor_types';
|
||||||
import { ILayer } from '../layer';
|
|
||||||
import { IField } from '../fields/field';
|
import { IField } from '../fields/field';
|
||||||
import { MAX_ZOOM, MIN_ZOOM } from '../../../common/constants';
|
import { MAX_ZOOM, MIN_ZOOM } from '../../../common/constants';
|
||||||
|
|
||||||
|
@ -37,7 +36,6 @@ export type PreIndexedShape = {
|
||||||
export type FieldFormatter = (value: string | number | null | undefined | boolean) => string;
|
export type FieldFormatter = (value: string | number | null | undefined | boolean) => string;
|
||||||
|
|
||||||
export interface ISource {
|
export interface ISource {
|
||||||
createDefaultLayer(options?: Partial<LayerDescriptor>): ILayer;
|
|
||||||
destroy(): void;
|
destroy(): void;
|
||||||
getDisplayName(): Promise<string>;
|
getDisplayName(): Promise<string>;
|
||||||
getInspectorAdapters(): Adapters | undefined;
|
getInspectorAdapters(): Adapters | undefined;
|
||||||
|
@ -59,7 +57,6 @@ export interface ISource {
|
||||||
getIndexPatternIds(): string[];
|
getIndexPatternIds(): string[];
|
||||||
getQueryableIndexPatternIds(): string[];
|
getQueryableIndexPatternIds(): string[];
|
||||||
getGeoGridPrecision(zoom: number): number;
|
getGeoGridPrecision(zoom: number): number;
|
||||||
shouldBeIndexed(): boolean;
|
|
||||||
getPreIndexedShape(): Promise<PreIndexedShape | null>;
|
getPreIndexedShape(): Promise<PreIndexedShape | null>;
|
||||||
createFieldFormatter(field: IField): Promise<FieldFormatter | null>;
|
createFieldFormatter(field: IField): Promise<FieldFormatter | null>;
|
||||||
getValueSuggestions(field: IField, query: string): Promise<string[]>;
|
getValueSuggestions(field: IField, query: string): Promise<string[]>;
|
||||||
|
@ -99,10 +96,6 @@ export class AbstractSource implements ISource {
|
||||||
return this._inspectorAdapters;
|
return this._inspectorAdapters;
|
||||||
}
|
}
|
||||||
|
|
||||||
createDefaultLayer(options?: Partial<LayerDescriptor>): ILayer {
|
|
||||||
throw new Error(`Source#createDefaultLayer not implemented`);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getDisplayName(): Promise<string> {
|
async getDisplayName(): Promise<string> {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
@ -155,10 +148,6 @@ export class AbstractSource implements ISource {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldBeIndexed(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
isESSource(): boolean {
|
isESSource(): boolean {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,7 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { VectorLayer } from '../../vector_layer';
|
|
||||||
import { TooltipProperty } from '../../tooltips/tooltip_property';
|
import { TooltipProperty } from '../../tooltips/tooltip_property';
|
||||||
import { VectorStyle } from '../../styles/vector/vector_style';
|
|
||||||
import { AbstractSource } from './../source';
|
import { AbstractSource } from './../source';
|
||||||
import * as topojson from 'topojson-client';
|
import * as topojson from 'topojson-client';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
@ -74,30 +72,10 @@ export class AbstractVectorSource extends AbstractSource {
|
||||||
return this.createField({ fieldName: name });
|
return this.createField({ fieldName: name });
|
||||||
}
|
}
|
||||||
|
|
||||||
_createDefaultLayerDescriptor(options, mapColors) {
|
|
||||||
return VectorLayer.createDescriptor(
|
|
||||||
{
|
|
||||||
sourceDescriptor: this._descriptor,
|
|
||||||
...options,
|
|
||||||
},
|
|
||||||
mapColors
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
_getTooltipPropertyNames() {
|
_getTooltipPropertyNames() {
|
||||||
return this._tooltipFields.map(field => field.getName());
|
return this._tooltipFields.map(field => field.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
createDefaultLayer(options, mapColors) {
|
|
||||||
const layerDescriptor = this._createDefaultLayerDescriptor(options, mapColors);
|
|
||||||
const style = new VectorStyle(layerDescriptor.style, this);
|
|
||||||
return new VectorLayer({
|
|
||||||
layerDescriptor: layerDescriptor,
|
|
||||||
source: this,
|
|
||||||
style,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
isFilterByMapBounds() {
|
isFilterByMapBounds() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,4 +4,5 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { WMSSource, wmsLayerWizardConfig } from './wms_source';
|
export { wmsLayerWizardConfig } from './wms_layer_wizard';
|
||||||
|
export { WMSSource } from './wms_source';
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
// @ts-ignore
|
||||||
|
import { WMSCreateSourceEditor } from './wms_create_source_editor';
|
||||||
|
// @ts-ignore
|
||||||
|
import { sourceTitle, WMSSource } from './wms_source';
|
||||||
|
import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry';
|
||||||
|
import { TileLayer } from '../../tile_layer';
|
||||||
|
|
||||||
|
export const wmsLayerWizardConfig: LayerWizard = {
|
||||||
|
description: i18n.translate('xpack.maps.source.wmsDescription', {
|
||||||
|
defaultMessage: 'Maps from OGC Standard WMS',
|
||||||
|
}),
|
||||||
|
icon: 'grid',
|
||||||
|
renderWizard: ({ previewLayer }: RenderWizardArguments) => {
|
||||||
|
const onSourceConfigChange = (sourceConfig: unknown) => {
|
||||||
|
if (!sourceConfig) {
|
||||||
|
previewLayer(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const layerDescriptor = TileLayer.createDescriptor({
|
||||||
|
sourceDescriptor: WMSSource.createDescriptor(sourceConfig),
|
||||||
|
});
|
||||||
|
previewLayer(layerDescriptor);
|
||||||
|
};
|
||||||
|
return <WMSCreateSourceEditor onSourceConfigChange={onSourceConfigChange} />;
|
||||||
|
},
|
||||||
|
title: sourceTitle,
|
||||||
|
};
|
|
@ -4,18 +4,14 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { AbstractTMSSource } from '../tms_source';
|
import { AbstractTMSSource } from '../tms_source';
|
||||||
import { TileLayer } from '../../tile_layer';
|
|
||||||
import { WMSCreateSourceEditor } from './wms_create_source_editor';
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { getDataSourceLabel, getUrlLabel } from '../../../../common/i18n_getters';
|
import { getDataSourceLabel, getUrlLabel } from '../../../../common/i18n_getters';
|
||||||
import { WmsClient } from './wms_client';
|
import { WmsClient } from './wms_client';
|
||||||
import { SOURCE_TYPES } from '../../../../common/constants';
|
import { SOURCE_TYPES } from '../../../../common/constants';
|
||||||
import { registerSource } from '../source_registry';
|
import { registerSource } from '../source_registry';
|
||||||
|
|
||||||
const sourceTitle = i18n.translate('xpack.maps.source.wmsTitle', {
|
export const sourceTitle = i18n.translate('xpack.maps.source.wmsTitle', {
|
||||||
defaultMessage: 'Web Map Service',
|
defaultMessage: 'Web Map Service',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -52,20 +48,6 @@ export class WMSSource extends AbstractTMSSource {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
_createDefaultLayerDescriptor(options) {
|
|
||||||
return TileLayer.createDescriptor({
|
|
||||||
sourceDescriptor: this._descriptor,
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
createDefaultLayer(options) {
|
|
||||||
return new TileLayer({
|
|
||||||
layerDescriptor: this._createDefaultLayerDescriptor(options),
|
|
||||||
source: this,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async getDisplayName() {
|
async getDisplayName() {
|
||||||
return this._descriptor.serviceUrl;
|
return this._descriptor.serviceUrl;
|
||||||
}
|
}
|
||||||
|
@ -94,24 +76,3 @@ registerSource({
|
||||||
ConstructorFunction: WMSSource,
|
ConstructorFunction: WMSSource,
|
||||||
type: SOURCE_TYPES.WMS,
|
type: SOURCE_TYPES.WMS,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const wmsLayerWizardConfig = {
|
|
||||||
description: i18n.translate('xpack.maps.source.wmsDescription', {
|
|
||||||
defaultMessage: 'Maps from OGC Standard WMS',
|
|
||||||
}),
|
|
||||||
icon: 'grid',
|
|
||||||
renderWizard: ({ onPreviewSource, inspectorAdapters }) => {
|
|
||||||
const onSourceConfigChange = sourceConfig => {
|
|
||||||
if (!sourceConfig) {
|
|
||||||
onPreviewSource(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sourceDescriptor = WMSSource.createDescriptor(sourceConfig);
|
|
||||||
const source = new WMSSource(sourceDescriptor, inspectorAdapters);
|
|
||||||
onPreviewSource(source);
|
|
||||||
};
|
|
||||||
return <WMSCreateSourceEditor onSourceConfigChange={onSourceConfigChange} />;
|
|
||||||
},
|
|
||||||
title: sourceTitle,
|
|
||||||
};
|
|
||||||
|
|
|
@ -9,17 +9,19 @@ import React from 'react';
|
||||||
import { XYZTMSEditor, XYZTMSSourceConfig } from './xyz_tms_editor';
|
import { XYZTMSEditor, XYZTMSSourceConfig } from './xyz_tms_editor';
|
||||||
import { XYZTMSSource, sourceTitle } from './xyz_tms_source';
|
import { XYZTMSSource, sourceTitle } from './xyz_tms_source';
|
||||||
import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry';
|
import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry';
|
||||||
|
import { TileLayer } from '../../tile_layer';
|
||||||
|
|
||||||
export const tmsLayerWizardConfig: LayerWizard = {
|
export const tmsLayerWizardConfig: LayerWizard = {
|
||||||
description: i18n.translate('xpack.maps.source.ems_xyzDescription', {
|
description: i18n.translate('xpack.maps.source.ems_xyzDescription', {
|
||||||
defaultMessage: 'Tile map service configured in interface',
|
defaultMessage: 'Tile map service configured in interface',
|
||||||
}),
|
}),
|
||||||
icon: 'grid',
|
icon: 'grid',
|
||||||
renderWizard: ({ onPreviewSource }: RenderWizardArguments) => {
|
renderWizard: ({ previewLayer }: RenderWizardArguments) => {
|
||||||
const onSourceConfigChange = (sourceConfig: XYZTMSSourceConfig) => {
|
const onSourceConfigChange = (sourceConfig: XYZTMSSourceConfig) => {
|
||||||
const sourceDescriptor = XYZTMSSource.createDescriptor(sourceConfig);
|
const layerDescriptor = TileLayer.createDescriptor({
|
||||||
const source = new XYZTMSSource(sourceDescriptor);
|
sourceDescriptor: XYZTMSSource.createDescriptor(sourceConfig),
|
||||||
onPreviewSource(source);
|
});
|
||||||
|
previewLayer(layerDescriptor);
|
||||||
};
|
};
|
||||||
return <XYZTMSEditor onSourceConfigChange={onSourceConfigChange} />;
|
return <XYZTMSEditor onSourceConfigChange={onSourceConfigChange} />;
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { XYZTMSSource } from './xyz_tms_source';
|
import { XYZTMSSource } from './xyz_tms_source';
|
||||||
import { ILayer } from '../../layer';
|
|
||||||
import { TileLayer } from '../../tile_layer';
|
|
||||||
import { SOURCE_TYPES } from '../../../../common/constants';
|
import { SOURCE_TYPES } from '../../../../common/constants';
|
||||||
import { XYZTMSSourceDescriptor } from '../../../../common/descriptor_types';
|
import { XYZTMSSourceDescriptor } from '../../../../common/descriptor_types';
|
||||||
|
|
||||||
|
@ -16,12 +14,6 @@ const descriptor: XYZTMSSourceDescriptor = {
|
||||||
id: 'foobar',
|
id: 'foobar',
|
||||||
};
|
};
|
||||||
describe('xyz Tilemap Source', () => {
|
describe('xyz Tilemap Source', () => {
|
||||||
it('should create a tile-layer', () => {
|
|
||||||
const source = new XYZTMSSource(descriptor);
|
|
||||||
const layer: ILayer = source.createDefaultLayer();
|
|
||||||
expect(layer instanceof TileLayer).toEqual(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should echo url template for url template', async () => {
|
it('should echo url template for url template', async () => {
|
||||||
const source = new XYZTMSSource(descriptor);
|
const source = new XYZTMSSource(descriptor);
|
||||||
const template = await source.getUrlTemplate();
|
const template = await source.getUrlTemplate();
|
||||||
|
|
|
@ -5,15 +5,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { TileLayer } from '../../tile_layer';
|
|
||||||
import { getDataSourceLabel, getUrlLabel } from '../../../../common/i18n_getters';
|
import { getDataSourceLabel, getUrlLabel } from '../../../../common/i18n_getters';
|
||||||
import { SOURCE_TYPES } from '../../../../common/constants';
|
import { SOURCE_TYPES } from '../../../../common/constants';
|
||||||
import { registerSource } from '../source_registry';
|
import { registerSource } from '../source_registry';
|
||||||
import { AbstractTMSSource } from '../tms_source';
|
import { AbstractTMSSource } from '../tms_source';
|
||||||
import { LayerDescriptor, XYZTMSSourceDescriptor } from '../../../../common/descriptor_types';
|
import { XYZTMSSourceDescriptor } from '../../../../common/descriptor_types';
|
||||||
import { Attribution, ImmutableSourceProperty } from '../source';
|
import { Attribution, ImmutableSourceProperty } from '../source';
|
||||||
import { XYZTMSSourceConfig } from './xyz_tms_editor';
|
import { XYZTMSSourceConfig } from './xyz_tms_editor';
|
||||||
import { ILayer } from '../../layer';
|
|
||||||
|
|
||||||
export const sourceTitle = i18n.translate('xpack.maps.source.ems_xyzTitle', {
|
export const sourceTitle = i18n.translate('xpack.maps.source.ems_xyzTitle', {
|
||||||
defaultMessage: 'Tile Map Service',
|
defaultMessage: 'Tile Map Service',
|
||||||
|
@ -49,17 +47,6 @@ export class XYZTMSSource extends AbstractTMSSource {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
createDefaultLayer(options?: LayerDescriptor): ILayer {
|
|
||||||
const layerDescriptor: LayerDescriptor = TileLayer.createDescriptor({
|
|
||||||
sourceDescriptor: this._descriptor,
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
return new TileLayer({
|
|
||||||
layerDescriptor,
|
|
||||||
source: this,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async getDisplayName(): Promise<string> {
|
async getDisplayName(): Promise<string> {
|
||||||
return this._descriptor.urlTemplate;
|
return this._descriptor.urlTemplate;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,6 @@ class MockTileSource extends AbstractTMSSource implements ITMSSource {
|
||||||
super(descriptor, {});
|
super(descriptor, {});
|
||||||
this._descriptor = descriptor;
|
this._descriptor = descriptor;
|
||||||
}
|
}
|
||||||
createDefaultLayer(): ILayer {
|
|
||||||
throw new Error('not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
async getDisplayName(): Promise<string> {
|
async getDisplayName(): Promise<string> {
|
||||||
return this._descriptor.urlTemplate;
|
return this._descriptor.urlTemplate;
|
||||||
|
|
|
@ -8819,10 +8819,8 @@
|
||||||
"xpack.logstash.workersTooltip": "パイプラインのフィルターとアウトプットステージを同時に実行するワーカーの数です。イベントが詰まってしまう場合や CPU が飽和状態ではない場合は、マシンの処理能力をより有効に活用するため、この数字を上げてみてください。\n\nデフォルト値:ホストの CPU コア数です",
|
"xpack.logstash.workersTooltip": "パイプラインのフィルターとアウトプットステージを同時に実行するワーカーの数です。イベントが詰まってしまう場合や CPU が飽和状態ではない場合は、マシンの処理能力をより有効に活用するため、この数字を上げてみてください。\n\nデフォルト値:ホストの CPU コア数です",
|
||||||
"xpack.maps.addLayerPanel.addLayer": "レイヤーを追加",
|
"xpack.maps.addLayerPanel.addLayer": "レイヤーを追加",
|
||||||
"xpack.maps.addLayerPanel.changeDataSourceButtonLabel": "データソースを変更",
|
"xpack.maps.addLayerPanel.changeDataSourceButtonLabel": "データソースを変更",
|
||||||
"xpack.maps.addLayerPanel.chooseDataSourceTitle": "データソースの選択",
|
|
||||||
"xpack.maps.addLayerPanel.footer.cancelButtonLabel": "キャンセル",
|
"xpack.maps.addLayerPanel.footer.cancelButtonLabel": "キャンセル",
|
||||||
"xpack.maps.addLayerPanel.importFile": "ファイルのインポート",
|
"xpack.maps.addLayerPanel.importFile": "ファイルのインポート",
|
||||||
"xpack.maps.addLayerPanel.selectSource": "ソースを選択",
|
|
||||||
"xpack.maps.aggs.defaultCountLabel": "カウント",
|
"xpack.maps.aggs.defaultCountLabel": "カウント",
|
||||||
"xpack.maps.appDescription": "マップアプリケーション",
|
"xpack.maps.appDescription": "マップアプリケーション",
|
||||||
"xpack.maps.appTitle": "マップ",
|
"xpack.maps.appTitle": "マップ",
|
||||||
|
|
|
@ -8822,10 +8822,8 @@
|
||||||
"xpack.logstash.workersTooltip": "并行执行管道的筛选和输出阶段的工作线程数目。如果您发现事件出现积压或 CPU 未饱和,请考虑增大此数值,以更好地利用机器处理能力。\n\n默认值:主机的 CPU 核心数",
|
"xpack.logstash.workersTooltip": "并行执行管道的筛选和输出阶段的工作线程数目。如果您发现事件出现积压或 CPU 未饱和,请考虑增大此数值,以更好地利用机器处理能力。\n\n默认值:主机的 CPU 核心数",
|
||||||
"xpack.maps.addLayerPanel.addLayer": "添加图层",
|
"xpack.maps.addLayerPanel.addLayer": "添加图层",
|
||||||
"xpack.maps.addLayerPanel.changeDataSourceButtonLabel": "更改数据源",
|
"xpack.maps.addLayerPanel.changeDataSourceButtonLabel": "更改数据源",
|
||||||
"xpack.maps.addLayerPanel.chooseDataSourceTitle": "选择数据源",
|
|
||||||
"xpack.maps.addLayerPanel.footer.cancelButtonLabel": "鍙栨秷",
|
"xpack.maps.addLayerPanel.footer.cancelButtonLabel": "鍙栨秷",
|
||||||
"xpack.maps.addLayerPanel.importFile": "导入文件",
|
"xpack.maps.addLayerPanel.importFile": "导入文件",
|
||||||
"xpack.maps.addLayerPanel.selectSource": "选择源",
|
|
||||||
"xpack.maps.aggs.defaultCountLabel": "计数",
|
"xpack.maps.aggs.defaultCountLabel": "计数",
|
||||||
"xpack.maps.appDescription": "地图应用程序",
|
"xpack.maps.appDescription": "地图应用程序",
|
||||||
"xpack.maps.appTitle": "Maps",
|
"xpack.maps.appTitle": "Maps",
|
||||||
|
|
Loading…
Reference in a new issue