[Maps] rename VectorLayer to GeoJsonVectorLayer and TiledVectorLayer to MvtVectorLayer (#117207)

* [Maps] rename VectorLayer to GeoJsonVectorLayer and TiledVectorLayer to MvtVectorLayer

* fix jest test

* eslint

* review feedback

* eslint

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Nathan Reese 2021-11-08 10:45:57 -07:00 committed by GitHub
parent b1e48fb96a
commit 635cad4817
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 597 additions and 513 deletions

View file

@ -85,7 +85,6 @@ export const SOURCE_DATA_REQUEST_ID = 'source';
export const SOURCE_META_DATA_REQUEST_ID = `${SOURCE_DATA_REQUEST_ID}_${META_DATA_REQUEST_ID_SUFFIX}`;
export const SOURCE_FORMATTERS_DATA_REQUEST_ID = `${SOURCE_DATA_REQUEST_ID}_${FORMATTERS_DATA_REQUEST_ID_SUFFIX}`;
export const SOURCE_BOUNDS_DATA_REQUEST_ID = `${SOURCE_DATA_REQUEST_ID}_bounds`;
export const SUPPORTS_FEATURE_EDITING_REQUEST_ID = 'SUPPORTS_FEATURE_EDITING_REQUEST_ID';
export const MIN_ZOOM = 0;
export const MAX_ZOOM = 24;

View file

@ -61,7 +61,7 @@ import { MapSettings } from '../reducers/map';
import { DrawState, MapCenterAndZoom, MapExtent, Timeslice } from '../../common/descriptor_types';
import { INITIAL_LOCATION } from '../../common/constants';
import { updateTooltipStateForLayer } from './tooltip_actions';
import { VectorLayer } from '../classes/layers/vector_layer';
import { isVectorLayer, IVectorLayer } from '../classes/layers/vector_layer';
import { SET_DRAW_MODE } from './ui_actions';
import { expandToTileBoundaries } from '../classes/util/geo_tile_utils';
import { getToasts } from '../kibana_services';
@ -357,12 +357,12 @@ export function addNewFeatureToIndex(geometry: Geometry | Position[]) {
return;
}
const layer = getLayerById(layerId, getState());
if (!layer || !(layer instanceof VectorLayer)) {
if (!layer || !isVectorLayer(layer)) {
return;
}
try {
await layer.addFeature(geometry);
await (layer as IVectorLayer).addFeature(geometry);
await dispatch(syncDataForLayerDueToDrawing(layer));
} catch (e) {
getToasts().addError(e, {
@ -385,11 +385,11 @@ export function deleteFeatureFromIndex(featureId: string) {
return;
}
const layer = getLayerById(layerId, getState());
if (!layer || !(layer instanceof VectorLayer)) {
if (!layer || !isVectorLayer(layer)) {
return;
}
try {
await layer.deleteFeature(featureId);
await (layer as IVectorLayer).deleteFeature(featureId);
await dispatch(syncDataForLayerDueToDrawing(layer));
} catch (e) {
getToasts().addError(e, {

View file

@ -23,7 +23,7 @@ import {
ESSearchSourceDescriptor,
} from '../../../../common/descriptor_types';
import { VectorStyle } from '../../styles/vector/vector_style';
import { VectorLayer } from '../vector_layer';
import { GeoJsonVectorLayer } from '../vector_layer';
import { EMSFileSource } from '../../sources/ems_file_source';
// @ts-ignore
import { ESSearchSource } from '../../sources/es_search_source';
@ -51,7 +51,7 @@ function createChoroplethLayerDescriptor({
aggFieldName: '',
rightSourceId: joinId,
});
return VectorLayer.createDescriptor({
return GeoJsonVectorLayer.createDescriptor({
joins: [
{
leftField,

View file

@ -22,7 +22,7 @@ import {
} from '../../../common/constants';
import { VectorStyle } from '../styles/vector/vector_style';
import { EMSFileSource } from '../sources/ems_file_source';
import { VectorLayer } from './vector_layer';
import { GeoJsonVectorLayer } from './vector_layer';
import { getDefaultDynamicProperties } from '../styles/vector/vector_style_defaults';
import { NUMERICAL_COLOR_PALETTES } from '../styles/color_palettes';
import { getJoinAggKey } from '../../../common/get_agg_key';
@ -97,7 +97,7 @@ export function createRegionMapLayerDescriptor({
if (termsSize !== undefined) {
termSourceDescriptor.size = termsSize;
}
return VectorLayer.createDescriptor({
return GeoJsonVectorLayer.createDescriptor({
label,
joins: [
{

View file

@ -24,7 +24,7 @@ import {
} from '../../../common/constants';
import { VectorStyle } from '../styles/vector/vector_style';
import { ESGeoGridSource } from '../sources/es_geo_grid_source';
import { VectorLayer } from './vector_layer';
import { GeoJsonVectorLayer } from './vector_layer';
import { HeatmapLayer } from './heatmap_layer';
import { getDefaultDynamicProperties } from '../styles/vector/vector_style_defaults';
import { NUMERICAL_COLOR_PALETTES } from '../styles/color_palettes';
@ -162,7 +162,7 @@ export function createTileMapLayerDescriptor({
};
}
return VectorLayer.createDescriptor({
return GeoJsonVectorLayer.createDescriptor({
label,
sourceDescriptor: geoGridSourceDescriptor,
style: VectorStyle.createDescriptor(styleProperties),

View file

@ -12,7 +12,7 @@ import { FeatureCollection } from 'geojson';
import { EuiPanel } from '@elastic/eui';
import { DEFAULT_MAX_RESULT_WINDOW, SCALING_TYPES } from '../../../../common/constants';
import { GeoJsonFileSource } from '../../sources/geojson_file_source';
import { VectorLayer } from '../../layers/vector_layer';
import { GeoJsonVectorLayer } from '../../layers/vector_layer';
import { createDefaultLayerDescriptor } from '../../sources/es_search_source';
import { RenderWizardArguments } from '../../layers/layer_wizard_registry';
import { FileUploadGeoResults } from '../../../../../file_upload/public';
@ -113,7 +113,7 @@ export class ClientFileCreateSourceEditor extends Component<RenderWizardArgument
: null,
name,
});
const layerDescriptor = VectorLayer.createDescriptor(
const layerDescriptor = GeoJsonVectorLayer.createDescriptor(
{ sourceDescriptor },
this.props.mapColors
);

View file

@ -20,13 +20,11 @@ import { buildVectorRequestMeta } from '../build_vector_request_meta';
const SCALED_PROPERTY_NAME = '__kbn_heatmap_weight__'; // unique name to store scaled value for weighting
export class HeatmapLayer extends AbstractLayer {
static type = LAYER_TYPE.HEATMAP;
private readonly _style: HeatmapStyle;
static createDescriptor(options: Partial<HeatmapLayerDescriptor>) {
const heatmapLayerDescriptor = super.createDescriptor(options);
heatmapLayerDescriptor.type = HeatmapLayer.type;
heatmapLayerDescriptor.type = LAYER_TYPE.HEATMAP;
heatmapLayerDescriptor.style = HeatmapStyle.createDescriptor();
return heatmapLayerDescriptor;
}

View file

@ -10,7 +10,7 @@ import { EuiPanel, EuiCallOut } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { createNewIndexAndPattern } from './create_new_index_pattern';
import { RenderWizardArguments } from '../layer_wizard_registry';
import { VectorLayer } from '../vector_layer';
import { GeoJsonVectorLayer } from '../vector_layer';
import { ESSearchSource } from '../../sources/es_search_source';
import { ADD_LAYER_STEP_ID } from '../../../connected_components/add_layer_panel/view';
import { getFileUpload, getIndexNameFormComponent } from '../../../kibana_services';
@ -127,7 +127,7 @@ export class NewVectorLayerEditor extends Component<RenderWizardArguments, State
geoField: 'coordinates',
filterByMapBounds: false,
});
const layerDescriptor = VectorLayer.createDescriptor(
const layerDescriptor = GeoJsonVectorLayer.createDescriptor(
{ sourceDescriptor },
this.props.mapColors
);

View file

@ -33,7 +33,7 @@ import { DISPLAY } from './display_select';
import { VectorStyle } from '../../../styles/vector/vector_style';
import { EMSFileSource } from '../../../sources/ems_file_source';
import { ESGeoGridSource } from '../../../sources/es_geo_grid_source';
import { VectorLayer } from '../../vector_layer';
import { GeoJsonVectorLayer } from '../../vector_layer';
import { HeatmapLayer } from '../../heatmap_layer';
import { getDefaultDynamicProperties } from '../../../styles/vector/vector_style_defaults';
@ -164,7 +164,7 @@ export function createLayerDescriptor({
aggFieldName: 'field' in metricsDescriptor ? metricsDescriptor.field : '',
rightSourceId: joinId,
});
return VectorLayer.createDescriptor({
return GeoJsonVectorLayer.createDescriptor({
label,
joins: [
{
@ -244,7 +244,7 @@ export function createLayerDescriptor({
},
};
return VectorLayer.createDescriptor({
return GeoJsonVectorLayer.createDescriptor({
label,
query: apmSourceQuery,
sourceDescriptor: geoGridSourceDescriptor,

View file

@ -22,7 +22,7 @@ import {
SYMBOLIZE_AS_TYPES,
VECTOR_STYLES,
} from '../../../../../common/constants';
import { VectorLayer } from '../../vector_layer';
import { GeoJsonVectorLayer } from '../../vector_layer';
import { VectorStyle } from '../../../styles/vector/vector_style';
// @ts-ignore
import { ESSearchSource } from '../../../sources/es_search_source';
@ -93,7 +93,7 @@ function createSourceLayerDescriptor(indexPatternId: string, indexPatternTitle:
[VECTOR_STYLES.ICON_SIZE]: { type: STYLE_TYPE.STATIC, options: { size: 8 } },
};
return VectorLayer.createDescriptor({
return GeoJsonVectorLayer.createDescriptor({
label: i18n.translate('xpack.maps.sescurity.sourceLayerLabel', {
defaultMessage: '{indexPatternTitle} | Source Point',
values: { indexPatternTitle },
@ -146,7 +146,7 @@ function createDestinationLayerDescriptor(indexPatternId: string, indexPatternTi
[VECTOR_STYLES.ICON_SIZE]: { type: STYLE_TYPE.STATIC, options: { size: 8 } },
};
return VectorLayer.createDescriptor({
return GeoJsonVectorLayer.createDescriptor({
label: i18n.translate('xpack.maps.sescurity.destinationLayerLabel', {
defaultMessage: '{indexPatternTitle} | Destination point',
values: { indexPatternTitle },
@ -192,7 +192,7 @@ function createLineLayerDescriptor(indexPatternId: string, indexPatternTitle: st
},
};
return VectorLayer.createDescriptor({
return GeoJsonVectorLayer.createDescriptor({
label: i18n.translate('xpack.maps.sescurity.lineLayerLabel', {
defaultMessage: '{indexPatternTitle} | Line',
values: { indexPatternTitle },

View file

@ -11,11 +11,9 @@ import { SOURCE_DATA_REQUEST_ID, LAYER_TYPE, LAYER_STYLE_TYPE } from '../../../.
import { TileStyle } from '../../styles/tile/tile_style';
export class TileLayer extends AbstractLayer {
static type = LAYER_TYPE.TILE;
static createDescriptor(options, mapColors) {
const tileLayerDescriptor = super.createDescriptor(options, mapColors);
tileLayerDescriptor.type = TileLayer.type;
tileLayerDescriptor.type = LAYER_TYPE.TILE;
tileLayerDescriptor.alpha = _.get(options, 'alpha', 1);
tileLayerDescriptor.style = { type: LAYER_STYLE_TYPE.TILE };
return tileLayerDescriptor;

View file

@ -5,15 +5,15 @@
* 2.0.
*/
import { SCALING_TYPES, SOURCE_TYPES } from '../../../../common/constants';
import { SCALING_TYPES, SOURCE_TYPES } from '../../../../../common/constants';
import { BlendedVectorLayer } from './blended_vector_layer';
import { ESSearchSource } from '../../sources/es_search_source';
import { ESSearchSource } from '../../../sources/es_search_source';
import {
AbstractESSourceDescriptor,
ESGeoGridSourceDescriptor,
} from '../../../../common/descriptor_types';
} from '../../../../../common/descriptor_types';
jest.mock('../../../kibana_services', () => {
jest.mock('../../../../kibana_services', () => {
return {
getIsDarkMode() {
return false;

View file

@ -6,11 +6,12 @@
*/
import { i18n } from '@kbn/i18n';
import { IVectorLayer, VectorLayer } from '../vector_layer';
import { IVectorStyle, VectorStyle } from '../../styles/vector/vector_style';
import { getDefaultDynamicProperties } from '../../styles/vector/vector_style_defaults';
import { IDynamicStyleProperty } from '../../styles/vector/properties/dynamic_style_property';
import { IStyleProperty } from '../../styles/vector/properties/style_property';
import { IVectorLayer } from '../vector_layer';
import { GeoJsonVectorLayer } from '../geojson_vector_layer';
import { IVectorStyle, VectorStyle } from '../../../styles/vector/vector_style';
import { getDefaultDynamicProperties } from '../../../styles/vector/vector_style_defaults';
import { IDynamicStyleProperty } from '../../../styles/vector/properties/dynamic_style_property';
import { IStyleProperty } from '../../../styles/vector/properties/style_property';
import {
COUNT_PROP_LABEL,
COUNT_PROP_NAME,
@ -21,13 +22,13 @@ import {
VECTOR_STYLES,
LAYER_STYLE_TYPE,
FIELD_ORIGIN,
} from '../../../../common/constants';
import { ESGeoGridSource } from '../../sources/es_geo_grid_source/es_geo_grid_source';
import { canSkipSourceUpdate } from '../../util/can_skip_fetch';
import { IESSource } from '../../sources/es_source';
import { ISource } from '../../sources/source';
import { DataRequestContext } from '../../../actions';
import { DataRequestAbortError } from '../../util/data_request';
} from '../../../../../common/constants';
import { ESGeoGridSource } from '../../../sources/es_geo_grid_source/es_geo_grid_source';
import { canSkipSourceUpdate } from '../../../util/can_skip_fetch';
import { IESSource } from '../../../sources/es_source';
import { ISource } from '../../../sources/source';
import { DataRequestContext } from '../../../../actions';
import { DataRequestAbortError } from '../../../util/data_request';
import {
VectorStyleDescriptor,
SizeDynamicOptions,
@ -37,11 +38,11 @@ import {
VectorLayerDescriptor,
VectorSourceRequestMeta,
VectorStylePropertiesDescriptor,
} from '../../../../common/descriptor_types';
import { IVectorSource } from '../../sources/vector_source';
import { LICENSED_FEATURES } from '../../../licensed_features';
import { ESSearchSource } from '../../sources/es_search_source/es_search_source';
import { isSearchSourceAbortError } from '../../sources/es_source/es_source';
} from '../../../../../common/descriptor_types';
import { IVectorSource } from '../../../sources/vector_source';
import { LICENSED_FEATURES } from '../../../../licensed_features';
import { ESSearchSource } from '../../../sources/es_search_source/es_search_source';
import { isSearchSourceAbortError } from '../../../sources/es_source/es_source';
const ACTIVE_COUNT_DATA_ID = 'ACTIVE_COUNT_DATA_ID';
@ -170,14 +171,12 @@ export interface BlendedVectorLayerArguments {
layerDescriptor: VectorLayerDescriptor;
}
export class BlendedVectorLayer extends VectorLayer implements IVectorLayer {
static type = LAYER_TYPE.BLENDED_VECTOR;
export class BlendedVectorLayer extends GeoJsonVectorLayer implements IVectorLayer {
static createDescriptor(
options: Partial<VectorLayerDescriptor>,
mapColors: string[]
): VectorLayerDescriptor {
const layerDescriptor = VectorLayer.createDescriptor(options, mapColors);
const layerDescriptor = GeoJsonVectorLayer.createDescriptor(options, mapColors);
layerDescriptor.type = LAYER_TYPE.BLENDED_VECTOR;
return layerDescriptor;
}

View file

@ -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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
export { BlendedVectorLayer } from './blended_vector_layer';

View file

@ -0,0 +1,405 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiIcon } from '@elastic/eui';
import { Feature, FeatureCollection } from 'geojson';
import type { Map as MbMap, GeoJSONSource as MbGeoJSONSource } from '@kbn/mapbox-gl';
import {
EMPTY_FEATURE_COLLECTION,
FEATURE_VISIBLE_PROPERTY_NAME,
FIELD_ORIGIN,
LAYER_TYPE,
} from '../../../../../common/constants';
import {
StyleMetaDescriptor,
Timeslice,
VectorJoinSourceRequestMeta,
VectorLayerDescriptor,
} from '../../../../../common/descriptor_types';
import { PropertiesMap } from '../../../../../common/elasticsearch_util';
import { TimesliceMaskConfig } from '../../../util/mb_filter_expressions';
import { DataRequestContext } from '../../../../actions';
import { IVectorStyle, VectorStyle } from '../../../styles/vector/vector_style';
import { ISource } from '../../../sources/source';
import { IVectorSource } from '../../../sources/vector_source';
import { AbstractLayer, CustomIconAndTooltipContent } from '../../layer';
import { InnerJoin } from '../../../joins/inner_join';
import {
AbstractVectorLayer,
noResultsIcon,
NO_RESULTS_ICON_AND_TOOLTIPCONTENT,
} from '../vector_layer';
import { DataRequestAbortError } from '../../../util/data_request';
import { canSkipSourceUpdate } from '../../../util/can_skip_fetch';
import { getFeatureCollectionBounds } from '../../../util/get_feature_collection_bounds';
import { GEOJSON_FEATURE_ID_PROPERTY_NAME } from './assign_feature_ids';
import { addGeoJsonMbSource, syncVectorSource } from './utils';
import { JoinState, performInnerJoins } from './perform_inner_joins';
import { buildVectorRequestMeta } from '../../build_vector_request_meta';
export const SUPPORTS_FEATURE_EDITING_REQUEST_ID = 'SUPPORTS_FEATURE_EDITING_REQUEST_ID';
export class GeoJsonVectorLayer extends AbstractVectorLayer {
static createDescriptor(
options: Partial<VectorLayerDescriptor>,
mapColors?: string[]
): VectorLayerDescriptor {
const layerDescriptor = super.createDescriptor(options) as VectorLayerDescriptor;
layerDescriptor.type = LAYER_TYPE.VECTOR;
if (!options.style) {
const styleProperties = VectorStyle.createDefaultStyleProperties(mapColors ? mapColors : []);
layerDescriptor.style = VectorStyle.createDescriptor(styleProperties);
}
if (!options.joins) {
layerDescriptor.joins = [];
}
return layerDescriptor;
}
supportsFeatureEditing(): boolean {
const dataRequest = this.getDataRequest(SUPPORTS_FEATURE_EDITING_REQUEST_ID);
const data = dataRequest?.getData() as { supportsFeatureEditing: boolean } | undefined;
return data ? data.supportsFeatureEditing : false;
}
async getBounds(syncContext: DataRequestContext) {
const isStaticLayer = !this.getSource().isBoundsAware();
return isStaticLayer || this.hasJoins()
? getFeatureCollectionBounds(this._getSourceFeatureCollection(), this.hasJoins())
: super.getBounds(syncContext);
}
getCustomIconAndTooltipContent(): CustomIconAndTooltipContent {
const featureCollection = this._getSourceFeatureCollection();
if (!featureCollection || featureCollection.features.length === 0) {
return NO_RESULTS_ICON_AND_TOOLTIPCONTENT;
}
if (
this.getJoins().length &&
!featureCollection.features.some(
(feature) => feature.properties?.[FEATURE_VISIBLE_PROPERTY_NAME]
)
) {
return {
icon: noResultsIcon,
tooltipContent: i18n.translate('xpack.maps.vectorLayer.noResultsFoundInJoinTooltip', {
defaultMessage: `No matching results found in term joins`,
}),
};
}
const sourceDataRequest = this.getSourceDataRequest();
const { tooltipContent, areResultsTrimmed, isDeprecated } =
this.getSource().getSourceTooltipContent(sourceDataRequest);
return {
icon: isDeprecated ? (
<EuiIcon type="alert" color="danger" />
) : (
this.getCurrentStyle().getIcon()
),
tooltipContent,
areResultsTrimmed,
};
}
getFeatureId(feature: Feature): string | number | undefined {
return feature.properties?.[GEOJSON_FEATURE_ID_PROPERTY_NAME];
}
getFeatureById(id: string | number) {
const featureCollection = this._getSourceFeatureCollection();
if (!featureCollection) {
return null;
}
const targetFeature = featureCollection.features.find((feature) => {
return this.getFeatureId(feature) === id;
});
return targetFeature ? targetFeature : null;
}
async getStyleMetaDescriptorFromLocalFeatures(): Promise<StyleMetaDescriptor | null> {
const sourceDataRequest = this.getSourceDataRequest();
const style = this.getCurrentStyle();
if (!style || !sourceDataRequest) {
return null;
}
return await style.pluckStyleMetaFromSourceDataRequest(sourceDataRequest);
}
syncLayerWithMB(mbMap: MbMap, timeslice?: Timeslice) {
addGeoJsonMbSource(this._getMbSourceId(), this.getMbLayerIds(), mbMap);
this._syncFeatureCollectionWithMb(mbMap);
const timesliceMaskConfig = this._getTimesliceMaskConfig(timeslice);
this._setMbLabelProperties(mbMap, undefined, timesliceMaskConfig);
this._setMbPointsProperties(mbMap, undefined, timesliceMaskConfig);
this._setMbLinePolygonProperties(mbMap, undefined, timesliceMaskConfig);
}
_syncFeatureCollectionWithMb(mbMap: MbMap) {
const mbGeoJSONSource = mbMap.getSource(this.getId()) as MbGeoJSONSource;
const featureCollection = this._getSourceFeatureCollection();
const featureCollectionOnMap = AbstractLayer.getBoundDataForSource(mbMap, this.getId());
if (!featureCollection) {
if (featureCollectionOnMap) {
this.getCurrentStyle().clearFeatureState(featureCollectionOnMap, mbMap, this.getId());
}
mbGeoJSONSource.setData(EMPTY_FEATURE_COLLECTION);
return;
}
// "feature-state" data expressions are not supported with layout properties.
// To work around this limitation,
// scaled layout properties (like icon-size) must fall back to geojson property values :(
const hasGeoJsonProperties = this.getCurrentStyle().setFeatureStateAndStyleProps(
featureCollection,
mbMap,
this.getId()
);
if (featureCollection !== featureCollectionOnMap || hasGeoJsonProperties) {
mbGeoJSONSource.setData(featureCollection);
}
}
_getTimesliceMaskConfig(timeslice?: Timeslice): TimesliceMaskConfig | undefined {
if (!timeslice || this.hasJoins()) {
return;
}
const prevMeta = this.getSourceDataRequest()?.getMeta();
return prevMeta !== undefined && prevMeta.timesliceMaskField !== undefined
? {
timesliceMaskField: prevMeta.timesliceMaskField,
timeslice,
}
: undefined;
}
async syncData(syncContext: DataRequestContext) {
await this._syncData(syncContext, this.getSource(), this.getCurrentStyle());
}
// TLDR: Do not call getSource or getCurrentStyle in syncData flow. Use 'source' and 'style' arguments instead.
//
// 1) State is contained in the redux store. Layer instance state is readonly.
// 2) Even though data request descriptor updates trigger new instances for rendering,
// syncing data executes on a single object instance. Syncing data can not use updated redux store state.
//
// Blended layer data syncing branches on the source/style depending on whether clustering is used or not.
// Given 1 above, which source/style to use can not be stored in Layer instance state.
// Given 2 above, which source/style to use can not be pulled from data request state.
// Therefore, source and style are provided as arugments and must be used instead of calling getSource or getCurrentStyle.
async _syncData(syncContext: DataRequestContext, source: IVectorSource, style: IVectorStyle) {
if (this.isLoadingBounds()) {
return;
}
try {
await this._syncSourceStyleMeta(syncContext, source, style);
await this._syncSourceFormatters(syncContext, source, style);
const sourceResult = await syncVectorSource({
layerId: this.getId(),
layerName: await this.getDisplayName(source),
prevDataRequest: this.getSourceDataRequest(),
requestMeta: await this._getVectorSourceRequestMeta(
syncContext.isForceRefresh,
syncContext.dataFilters,
source,
style
),
syncContext,
source,
getUpdateDueToTimeslice: (timeslice?: Timeslice) => {
return this._getUpdateDueToTimesliceFromSourceRequestMeta(source, timeslice);
},
});
await this._syncSupportsFeatureEditing({ syncContext, source });
if (
!sourceResult.featureCollection ||
!sourceResult.featureCollection.features.length ||
!this.hasJoins()
) {
return;
}
const joinStates = await this._syncJoins(syncContext, style);
performInnerJoins(
sourceResult,
joinStates,
syncContext.updateSourceData,
syncContext.onJoinError
);
} catch (error) {
if (!(error instanceof DataRequestAbortError)) {
throw error;
}
}
}
async _syncJoin({
join,
startLoading,
stopLoading,
onLoadError,
registerCancelCallback,
dataFilters,
isForceRefresh,
}: { join: InnerJoin } & DataRequestContext): Promise<JoinState> {
const joinSource = join.getRightJoinSource();
const sourceDataId = join.getSourceDataRequestId();
const requestToken = Symbol(`layer-join-refresh:${this.getId()} - ${sourceDataId}`);
const joinRequestMeta: VectorJoinSourceRequestMeta = buildVectorRequestMeta(
joinSource,
joinSource.getFieldNames(),
dataFilters,
joinSource.getWhereQuery(),
isForceRefresh
) as VectorJoinSourceRequestMeta;
const prevDataRequest = this.getDataRequest(sourceDataId);
const canSkipFetch = await canSkipSourceUpdate({
source: joinSource,
prevDataRequest,
nextRequestMeta: joinRequestMeta,
extentAware: false, // join-sources are term-aggs that are spatially unaware (e.g. ESTermSource/TableSource).
getUpdateDueToTimeslice: () => {
return true;
},
});
if (canSkipFetch) {
return {
dataHasChanged: false,
join,
propertiesMap: prevDataRequest?.getData() as PropertiesMap,
};
}
try {
startLoading(sourceDataId, requestToken, joinRequestMeta);
const leftSourceName = await this._source.getDisplayName();
const propertiesMap = await joinSource.getPropertiesMap(
joinRequestMeta,
leftSourceName,
join.getLeftField().getName(),
registerCancelCallback.bind(null, requestToken)
);
stopLoading(sourceDataId, requestToken, propertiesMap);
return {
dataHasChanged: true,
join,
propertiesMap,
};
} catch (error) {
if (!(error instanceof DataRequestAbortError)) {
onLoadError(sourceDataId, requestToken, `Join error: ${error.message}`);
}
throw error;
}
}
async _syncJoins(syncContext: DataRequestContext, style: IVectorStyle) {
const joinSyncs = this.getValidJoins().map(async (join) => {
await this._syncJoinStyleMeta(syncContext, join, style);
await this._syncJoinFormatters(syncContext, join, style);
return this._syncJoin({ join, ...syncContext });
});
return await Promise.all(joinSyncs);
}
async _syncJoinStyleMeta(syncContext: DataRequestContext, join: InnerJoin, style: IVectorStyle) {
const joinSource = join.getRightJoinSource();
return this._syncStyleMeta({
source: joinSource,
style,
sourceQuery: joinSource.getWhereQuery(),
dataRequestId: join.getSourceMetaDataRequestId(),
dynamicStyleProps: this.getCurrentStyle()
.getDynamicPropertiesArray()
.filter((dynamicStyleProp) => {
const matchingField = joinSource.getFieldByName(dynamicStyleProp.getFieldName());
return (
dynamicStyleProp.getFieldOrigin() === FIELD_ORIGIN.JOIN &&
!!matchingField &&
dynamicStyleProp.isFieldMetaEnabled()
);
}),
...syncContext,
});
}
async _syncJoinFormatters(syncContext: DataRequestContext, join: InnerJoin, style: IVectorStyle) {
const joinSource = join.getRightJoinSource();
return this._syncFormatters({
source: joinSource,
dataRequestId: join.getSourceFormattersDataRequestId(),
fields: style
.getDynamicPropertiesArray()
.filter((dynamicStyleProp) => {
const matchingField = joinSource.getFieldByName(dynamicStyleProp.getFieldName());
return dynamicStyleProp.getFieldOrigin() === FIELD_ORIGIN.JOIN && !!matchingField;
})
.map((dynamicStyleProp) => {
return dynamicStyleProp.getField()!;
}),
...syncContext,
});
}
async _syncSupportsFeatureEditing({
syncContext,
source,
}: {
syncContext: DataRequestContext;
source: IVectorSource;
}) {
if (syncContext.dataFilters.isReadOnly) {
return;
}
const { startLoading, stopLoading, onLoadError } = syncContext;
const dataRequestId = SUPPORTS_FEATURE_EDITING_REQUEST_ID;
const requestToken = Symbol(`layer-${this.getId()}-${dataRequestId}`);
const prevDataRequest = this.getDataRequest(dataRequestId);
if (prevDataRequest) {
return;
}
try {
startLoading(dataRequestId, requestToken);
const supportsFeatureEditing = await source.supportsFeatureEditing();
stopLoading(dataRequestId, requestToken, { supportsFeatureEditing });
} catch (error) {
onLoadError(dataRequestId, requestToken, error.message);
throw error;
}
}
_getSourceFeatureCollection() {
const sourceDataRequest = this.getSourceDataRequest();
return sourceDataRequest ? (sourceDataRequest.getData() as FeatureCollection) : null;
}
_getUpdateDueToTimesliceFromSourceRequestMeta(source: ISource, timeslice?: Timeslice) {
const prevDataRequest = this.getSourceDataRequest();
const prevMeta = prevDataRequest?.getMeta();
if (!prevMeta) {
return true;
}
return source.getUpdateDueToTimeslice(prevMeta, timeslice);
}
}

View file

@ -21,7 +21,7 @@ import turfArea from '@turf/area';
import turfCenterOfMass from '@turf/center-of-mass';
import turfLength from '@turf/length';
import { lineString, polygon } from '@turf/helpers';
import { GEO_JSON_TYPE, KBN_IS_CENTROID_FEATURE } from '../../../../common/constants';
import { GEO_JSON_TYPE, KBN_IS_CENTROID_FEATURE } from '../../../../../common/constants';
export function getCentroidFeatures(featureCollection: FeatureCollection): Feature[] {
const centroids = [];

View file

@ -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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
export { GeoJsonVectorLayer } from './geojson_vector_layer';

View file

@ -8,16 +8,16 @@
import sinon from 'sinon';
import _ from 'lodash';
import { FeatureCollection } from 'geojson';
import { ESTermSourceDescriptor } from '../../../../common/descriptor_types';
import { ESTermSourceDescriptor } from '../../../../../common/descriptor_types';
import {
AGG_TYPE,
FEATURE_VISIBLE_PROPERTY_NAME,
SOURCE_TYPES,
} from '../../../../common/constants';
} from '../../../../../common/constants';
import { performInnerJoins } from './perform_inner_joins';
import { InnerJoin } from '../../joins/inner_join';
import { IVectorSource } from '../../sources/vector_source';
import { IField } from '../../fields/field';
import { InnerJoin } from '../../../joins/inner_join';
import { IVectorSource } from '../../../sources/vector_source';
import { IField } from '../../../fields/field';
const LEFT_FIELD = 'leftKey';
const COUNT_PROPERTY_NAME = '__kbnjoin__count__d3625663-5b34-4d50-a784-0d743f676a0c';

View file

@ -7,10 +7,10 @@
import { FeatureCollection } from 'geojson';
import { i18n } from '@kbn/i18n';
import { FEATURE_VISIBLE_PROPERTY_NAME } from '../../../../common/constants';
import { DataRequestContext } from '../../../actions';
import { InnerJoin } from '../../joins/inner_join';
import { PropertiesMap } from '../../../../common/elasticsearch_util';
import { FEATURE_VISIBLE_PROPERTY_NAME } from '../../../../../common/constants';
import { DataRequestContext } from '../../../../actions';
import { InnerJoin } from '../../../joins/inner_join';
import { PropertiesMap } from '../../../../../common/elasticsearch_util';
interface SourceResult {
refreshed: boolean;

View file

@ -13,19 +13,19 @@ import {
SOURCE_BOUNDS_DATA_REQUEST_ID,
SOURCE_DATA_REQUEST_ID,
VECTOR_SHAPE_TYPE,
} from '../../../../common/constants';
} from '../../../../../common/constants';
import {
DataRequestMeta,
MapExtent,
Timeslice,
VectorSourceRequestMeta,
} from '../../../../common/descriptor_types';
import { DataRequestContext } from '../../../actions';
import { IVectorSource } from '../../sources/vector_source';
import { DataRequestAbortError } from '../../util/data_request';
import { DataRequest } from '../../util/data_request';
} from '../../../../../common/descriptor_types';
import { DataRequestContext } from '../../../../actions';
import { IVectorSource } from '../../../sources/vector_source';
import { DataRequestAbortError } from '../../../util/data_request';
import { DataRequest } from '../../../util/data_request';
import { getCentroidFeatures } from './get_centroid_features';
import { canSkipSourceUpdate } from '../../util/can_skip_fetch';
import { canSkipSourceUpdate } from '../../../util/can_skip_fetch';
import { assignFeatureIds } from './assign_feature_ids';
export function addGeoJsonMbSource(mbSourceId: string, mbLayerIds: string[], mbMap: MbMap) {

View file

@ -5,6 +5,14 @@
* 2.0.
*/
export { addGeoJsonMbSource, getVectorSourceBounds, syncVectorSource } from './utils';
export {
addGeoJsonMbSource,
getVectorSourceBounds,
syncVectorSource,
} from './geojson_vector_layer/utils';
export type { IVectorLayer, VectorLayerArguments } from './vector_layer';
export { isVectorLayer, VectorLayer, NO_RESULTS_ICON_AND_TOOLTIPCONTENT } from './vector_layer';
export { isVectorLayer, NO_RESULTS_ICON_AND_TOOLTIPCONTENT } from './vector_layer';
export { BlendedVectorLayer } from './blended_vector_layer';
export { GeoJsonVectorLayer } from './geojson_vector_layer';
export { MvtVectorLayer } from './mvt_vector_layer';

View file

@ -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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
export { MvtVectorLayer } from './mvt_vector_layer';

View file

@ -5,11 +5,11 @@
* 2.0.
*/
import { MockSyncContext } from '../__fixtures__/mock_sync_context';
import { MockSyncContext } from '../../__fixtures__/mock_sync_context';
import sinon from 'sinon';
import url from 'url';
jest.mock('../../../kibana_services', () => {
jest.mock('../../../../kibana_services', () => {
return {
getIsDarkMode() {
return false;
@ -20,14 +20,14 @@ jest.mock('../../../kibana_services', () => {
import { shallow } from 'enzyme';
import { Feature } from 'geojson';
import { MVTSingleLayerVectorSource } from '../../sources/mvt_single_layer_vector_source';
import { MVTSingleLayerVectorSource } from '../../../sources/mvt_single_layer_vector_source';
import {
DataRequestDescriptor,
TiledSingleLayerVectorSourceDescriptor,
VectorLayerDescriptor,
} from '../../../../common/descriptor_types';
import { SOURCE_TYPES } from '../../../../common/constants';
import { TiledVectorLayer } from './tiled_vector_layer';
} from '../../../../../common/descriptor_types';
import { SOURCE_TYPES } from '../../../../../common/constants';
import { MvtVectorLayer } from './mvt_vector_layer';
const defaultConfig = {
urlTemplate: 'https://example.com/{x}/{y}/{z}.pbf',
@ -41,7 +41,7 @@ function createLayer(
sourceOptions: Partial<TiledSingleLayerVectorSourceDescriptor> = {},
isTimeAware: boolean = false,
includeToken: boolean = false
): TiledVectorLayer {
): MvtVectorLayer {
const sourceDescriptor: TiledSingleLayerVectorSourceDescriptor = {
type: SOURCE_TYPES.MVT_SINGLE_LAYER,
...defaultConfig,
@ -76,28 +76,28 @@ function createLayer(
...layerOptions,
sourceDescriptor,
};
const layerDescriptor = TiledVectorLayer.createDescriptor(defaultLayerOptions);
return new TiledVectorLayer({ layerDescriptor, source: mvtSource });
const layerDescriptor = MvtVectorLayer.createDescriptor(defaultLayerOptions);
return new MvtVectorLayer({ layerDescriptor, source: mvtSource });
}
describe('visiblity', () => {
it('should get minzoom from source', async () => {
const layer: TiledVectorLayer = createLayer({}, {});
const layer: MvtVectorLayer = createLayer({}, {});
expect(layer.getMinZoom()).toEqual(4);
});
it('should get maxzoom from default', async () => {
const layer: TiledVectorLayer = createLayer({}, {});
const layer: MvtVectorLayer = createLayer({}, {});
expect(layer.getMaxZoom()).toEqual(24);
});
it('should get maxzoom from layer options', async () => {
const layer: TiledVectorLayer = createLayer({ maxZoom: 10 }, {});
const layer: MvtVectorLayer = createLayer({ maxZoom: 10 }, {});
expect(layer.getMaxZoom()).toEqual(10);
});
});
describe('getCustomIconAndTooltipContent', () => {
it('Layers with non-elasticsearch sources should display icon', async () => {
const layer: TiledVectorLayer = createLayer({}, {});
const layer: MvtVectorLayer = createLayer({}, {});
const iconAndTooltipContent = layer.getCustomIconAndTooltipContent();
const component = shallow(iconAndTooltipContent.icon);
@ -107,7 +107,7 @@ describe('getCustomIconAndTooltipContent', () => {
describe('getFeatureById', () => {
it('should return null feature', async () => {
const layer: TiledVectorLayer = createLayer({}, {});
const layer: MvtVectorLayer = createLayer({}, {});
const feature = layer.getFeatureById('foobar') as Feature;
expect(feature).toEqual(null);
});
@ -115,7 +115,7 @@ describe('getFeatureById', () => {
describe('syncData', () => {
it('Should sync with source-params', async () => {
const layer: TiledVectorLayer = createLayer({}, {});
const layer: MvtVectorLayer = createLayer({}, {});
const syncContext = new MockSyncContext({ dataFilters: {} });
@ -138,7 +138,7 @@ describe('syncData', () => {
data: { ...defaultConfig },
dataId: 'source',
};
const layer: TiledVectorLayer = createLayer(
const layer: MvtVectorLayer = createLayer(
{
__dataRequests: [dataRequestDescriptor],
},
@ -157,7 +157,7 @@ describe('syncData', () => {
data: { ...defaultConfig },
dataId: 'source',
};
const layer: TiledVectorLayer = createLayer(
const layer: MvtVectorLayer = createLayer(
{
__dataRequests: [dataRequestDescriptor],
},
@ -187,7 +187,7 @@ describe('syncData', () => {
data: defaultConfig,
dataId: 'source',
};
const layer: TiledVectorLayer = createLayer(
const layer: MvtVectorLayer = createLayer(
{
__dataRequests: [dataRequestDescriptor],
},
@ -217,7 +217,7 @@ describe('syncData', () => {
const uuidRegex = /\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b/;
it(`should add token in url`, async () => {
const layer: TiledVectorLayer = createLayer({}, {}, false, true);
const layer: MvtVectorLayer = createLayer({}, {}, false, true);
const syncContext = new MockSyncContext({ dataFilters: {} });

View file

@ -16,38 +16,33 @@ import { i18n } from '@kbn/i18n';
import uuid from 'uuid/v4';
import { parse as parseUrl } from 'url';
import { euiThemeVars } from '@kbn/ui-shared-deps-src/theme';
import { IVectorStyle, VectorStyle } from '../../styles/vector/vector_style';
import { LAYER_TYPE, SOURCE_DATA_REQUEST_ID, SOURCE_TYPES } from '../../../../common/constants';
import { IVectorStyle, VectorStyle } from '../../../styles/vector/vector_style';
import { LAYER_TYPE, SOURCE_DATA_REQUEST_ID, SOURCE_TYPES } from '../../../../../common/constants';
import {
NO_RESULTS_ICON_AND_TOOLTIPCONTENT,
VectorLayer,
AbstractVectorLayer,
VectorLayerArguments,
} from '../vector_layer';
import { ITiledSingleLayerVectorSource } from '../../sources/tiled_single_layer_vector_source';
import { DataRequestContext } from '../../../actions';
import { ITiledSingleLayerVectorSource } from '../../../sources/tiled_single_layer_vector_source';
import { DataRequestContext } from '../../../../actions';
import {
StyleMetaDescriptor,
TileMetaFeature,
Timeslice,
VectorLayerDescriptor,
VectorSourceRequestMeta,
} from '../../../../common/descriptor_types';
import { MVTSingleLayerVectorSourceConfig } from '../../sources/mvt_single_layer_vector_source/types';
import { ESSearchSource } from '../../sources/es_search_source';
import { canSkipSourceUpdate } from '../../util/can_skip_fetch';
import { CustomIconAndTooltipContent } from '../layer';
} from '../../../../../common/descriptor_types';
import { MVTSingleLayerVectorSourceConfig } from '../../../sources/mvt_single_layer_vector_source/types';
import { ESSearchSource } from '../../../sources/es_search_source';
import { canSkipSourceUpdate } from '../../../util/can_skip_fetch';
import { CustomIconAndTooltipContent } from '../../layer';
const ES_MVT_META_LAYER_NAME = 'meta';
const ES_MVT_HITS_TOTAL_RELATION = 'hits.total.relation';
const ES_MVT_HITS_TOTAL_VALUE = 'hits.total.value';
const MAX_RESULT_WINDOW_DATA_REQUEST_ID = 'maxResultWindow';
/*
* MVT vector layer
*/
export class TiledVectorLayer extends VectorLayer {
static type = LAYER_TYPE.TILED_VECTOR;
export class MvtVectorLayer extends AbstractVectorLayer {
static createDescriptor(
descriptor: Partial<VectorLayerDescriptor>,
mapColors?: string[]

View file

@ -27,7 +27,7 @@ import {
import { ESTermSourceDescriptor, VectorStyleDescriptor } from '../../../../common/descriptor_types';
import { getDefaultDynamicProperties } from '../../styles/vector/vector_style_defaults';
import { IVectorSource } from '../../sources/vector_source';
import { VectorLayer } from './vector_layer';
import { AbstractVectorLayer } from './vector_layer';
class MockSource {
cloneDescriptor() {
@ -64,7 +64,7 @@ describe('cloneDescriptor', () => {
};
test('Should update data driven styling properties using join fields', async () => {
const layerDescriptor = VectorLayer.createDescriptor({
const layerDescriptor = AbstractVectorLayer.createDescriptor({
style: styleDescriptor,
joins: [
{
@ -83,7 +83,7 @@ describe('cloneDescriptor', () => {
},
],
});
const layer = new VectorLayer({
const layer = new AbstractVectorLayer({
layerDescriptor,
source: new MockSource() as unknown as IVectorSource,
});
@ -105,7 +105,7 @@ describe('cloneDescriptor', () => {
});
test('Should update data driven styling properties using join fields when metrics are not provided', async () => {
const layerDescriptor = VectorLayer.createDescriptor({
const layerDescriptor = AbstractVectorLayer.createDescriptor({
style: styleDescriptor,
joins: [
{
@ -120,7 +120,7 @@ describe('cloneDescriptor', () => {
},
],
});
const layer = new VectorLayer({
const layer = new AbstractVectorLayer({
layerDescriptor,
source: new MockSource() as unknown as IVectorSource,
});

View file

@ -7,13 +7,9 @@
import React from 'react';
import uuid from 'uuid/v4';
import type {
Map as MbMap,
AnyLayer as MbLayer,
GeoJSONSource as MbGeoJSONSource,
} from '@kbn/mapbox-gl';
import type { Map as MbMap, AnyLayer as MbLayer } from '@kbn/mapbox-gl';
import type { Query } from 'src/plugins/data/common';
import { Feature, FeatureCollection, GeoJsonProperties, Geometry, Position } from 'geojson';
import { Feature, GeoJsonProperties, Geometry, Position } from 'geojson';
import _ from 'lodash';
import { EuiIcon } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
@ -23,24 +19,16 @@ import {
AGG_TYPE,
SOURCE_META_DATA_REQUEST_ID,
SOURCE_FORMATTERS_DATA_REQUEST_ID,
FEATURE_VISIBLE_PROPERTY_NAME,
EMPTY_FEATURE_COLLECTION,
LAYER_TYPE,
FIELD_ORIGIN,
FieldFormatter,
SOURCE_TYPES,
STYLE_TYPE,
SUPPORTS_FEATURE_EDITING_REQUEST_ID,
VECTOR_STYLES,
} from '../../../../common/constants';
import { JoinTooltipProperty } from '../../tooltips/join_tooltip_property';
import { DataRequestAbortError } from '../../util/data_request';
import {
canSkipSourceUpdate,
canSkipStyleMetaUpdate,
canSkipFormattersUpdate,
} from '../../util/can_skip_fetch';
import { getFeatureCollectionBounds } from '../../util/get_feature_collection_bounds';
import { canSkipStyleMetaUpdate, canSkipFormattersUpdate } from '../../util/can_skip_fetch';
import {
getLabelFilterExpression,
getFillFilterExpression,
@ -55,13 +43,10 @@ import {
ESTermSourceDescriptor,
JoinDescriptor,
StyleMetaDescriptor,
Timeslice,
VectorLayerDescriptor,
VectorSourceRequestMeta,
VectorStyleRequestMeta,
VectorJoinSourceRequestMeta,
} from '../../../../common/descriptor_types';
import { ISource } from '../../sources/source';
import { IVectorSource } from '../../sources/vector_source';
import { CustomIconAndTooltipContent, ILayer } from '../layer';
import { InnerJoin } from '../../joins/inner_join';
@ -70,13 +55,10 @@ import { DataRequestContext } from '../../../actions';
import { ITooltipProperty } from '../../tooltips/tooltip_property';
import { IDynamicStyleProperty } from '../../styles/vector/properties/dynamic_style_property';
import { IESSource } from '../../sources/es_source';
import { PropertiesMap } from '../../../../common/elasticsearch_util';
import { ITermJoinSource } from '../../sources/term_join_source';
import { addGeoJsonMbSource, getVectorSourceBounds, syncVectorSource } from './utils';
import { JoinState, performInnerJoins } from './perform_inner_joins';
import { buildVectorRequestMeta } from '../build_vector_request_meta';
import { getJoinAggKey } from '../../../../common/get_agg_key';
import { GEOJSON_FEATURE_ID_PROPERTY_NAME } from './assign_feature_ids';
import { getVectorSourceBounds } from './geojson_vector_layer/utils';
export function isVectorLayer(layer: ILayer) {
return (layer as IVectorLayer).canShowTooltip !== undefined;
@ -114,7 +96,7 @@ export interface IVectorLayer extends ILayer {
deleteFeature(featureId: string): Promise<void>;
}
const noResultsIcon = <EuiIcon size="m" color="subdued" type="minusInCircle" />;
export const noResultsIcon = <EuiIcon size="m" color="subdued" type="minusInCircle" />;
export const NO_RESULTS_ICON_AND_TOOLTIPCONTENT = {
icon: noResultsIcon,
tooltipContent: i18n.translate('xpack.maps.vectorLayer.noResultsFoundTooltip', {
@ -122,12 +104,7 @@ export const NO_RESULTS_ICON_AND_TOOLTIPCONTENT = {
}),
};
/*
* Geojson vector layer
*/
export class VectorLayer extends AbstractLayer implements IVectorLayer {
static type = LAYER_TYPE.VECTOR;
export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer {
protected readonly _style: VectorStyle;
private readonly _joins: InnerJoin[];
@ -265,9 +242,7 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer {
}
supportsFeatureEditing(): boolean {
const dataRequest = this.getDataRequest(SUPPORTS_FEATURE_EDITING_REQUEST_ID);
const data = dataRequest?.getData() as { supportsFeatureEditing: boolean } | undefined;
return data ? data.supportsFeatureEditing : false;
return false;
}
hasJoins() {
@ -296,38 +271,7 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer {
}
getCustomIconAndTooltipContent(): CustomIconAndTooltipContent {
const featureCollection = this._getSourceFeatureCollection();
if (!featureCollection || featureCollection.features.length === 0) {
return NO_RESULTS_ICON_AND_TOOLTIPCONTENT;
}
if (
this.getJoins().length &&
!featureCollection.features.some(
(feature) => feature.properties?.[FEATURE_VISIBLE_PROPERTY_NAME]
)
) {
return {
icon: noResultsIcon,
tooltipContent: i18n.translate('xpack.maps.vectorLayer.noResultsFoundInJoinTooltip', {
defaultMessage: `No matching results found in term joins`,
}),
};
}
const sourceDataRequest = this.getSourceDataRequest();
const { tooltipContent, areResultsTrimmed, isDeprecated } =
this.getSource().getSourceTooltipContent(sourceDataRequest);
return {
icon: isDeprecated ? (
<EuiIcon type="alert" color="danger" />
) : (
this.getCurrentStyle().getIcon()
),
tooltipContent,
areResultsTrimmed,
};
throw new Error('Should implement AbstractVectorLayer#getCustomIconAndTooltipContent');
}
getLayerTypeIconName() {
@ -343,15 +287,12 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer {
}
async getBounds(syncContext: DataRequestContext) {
const isStaticLayer = !this.getSource().isBoundsAware();
return isStaticLayer || this.hasJoins()
? getFeatureCollectionBounds(this._getSourceFeatureCollection(), this.hasJoins())
: getVectorSourceBounds({
layerId: this.getId(),
syncContext,
source: this.getSource(),
sourceQuery: this.getQuery(),
});
return getVectorSourceBounds({
layerId: this.getId(),
syncContext,
source: this.getSource(),
sourceQuery: this.getQuery(),
});
}
async getLeftJoinFields() {
@ -409,79 +350,6 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer {
});
}
async _syncJoin({
join,
startLoading,
stopLoading,
onLoadError,
registerCancelCallback,
dataFilters,
isForceRefresh,
}: { join: InnerJoin } & DataRequestContext): Promise<JoinState> {
const joinSource = join.getRightJoinSource();
const sourceDataId = join.getSourceDataRequestId();
const requestToken = Symbol(`layer-join-refresh:${this.getId()} - ${sourceDataId}`);
const joinRequestMeta: VectorJoinSourceRequestMeta = buildVectorRequestMeta(
joinSource,
joinSource.getFieldNames(),
dataFilters,
joinSource.getWhereQuery(),
isForceRefresh
) as VectorJoinSourceRequestMeta;
const prevDataRequest = this.getDataRequest(sourceDataId);
const canSkipFetch = await canSkipSourceUpdate({
source: joinSource,
prevDataRequest,
nextRequestMeta: joinRequestMeta,
extentAware: false, // join-sources are term-aggs that are spatially unaware (e.g. ESTermSource/TableSource).
getUpdateDueToTimeslice: () => {
return true;
},
});
if (canSkipFetch) {
return {
dataHasChanged: false,
join,
propertiesMap: prevDataRequest?.getData() as PropertiesMap,
};
}
try {
startLoading(sourceDataId, requestToken, joinRequestMeta);
const leftSourceName = await this._source.getDisplayName();
const propertiesMap = await joinSource.getPropertiesMap(
joinRequestMeta,
leftSourceName,
join.getLeftField().getName(),
registerCancelCallback.bind(null, requestToken)
);
stopLoading(sourceDataId, requestToken, propertiesMap);
return {
dataHasChanged: true,
join,
propertiesMap,
};
} catch (error) {
if (!(error instanceof DataRequestAbortError)) {
onLoadError(sourceDataId, requestToken, `Join error: ${error.message}`);
}
throw error;
}
}
async _syncJoins(syncContext: DataRequestContext, style: IVectorStyle) {
const joinSyncs = this.getValidJoins().map(async (join) => {
await this._syncJoinStyleMeta(syncContext, join, style);
await this._syncJoinFormatters(syncContext, join, style);
return this._syncJoin({ join, ...syncContext });
});
return await Promise.all(joinSyncs);
}
async _getVectorSourceRequestMeta(
isForceRefresh: boolean,
dataFilters: DataFilters,
@ -522,27 +390,6 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer {
});
}
async _syncJoinStyleMeta(syncContext: DataRequestContext, join: InnerJoin, style: IVectorStyle) {
const joinSource = join.getRightJoinSource();
return this._syncStyleMeta({
source: joinSource,
style,
sourceQuery: joinSource.getWhereQuery(),
dataRequestId: join.getSourceMetaDataRequestId(),
dynamicStyleProps: this.getCurrentStyle()
.getDynamicPropertiesArray()
.filter((dynamicStyleProp) => {
const matchingField = joinSource.getFieldByName(dynamicStyleProp.getFieldName());
return (
dynamicStyleProp.getFieldOrigin() === FIELD_ORIGIN.JOIN &&
!!matchingField &&
dynamicStyleProp.isFieldMetaEnabled()
);
}),
...syncContext,
});
}
async _syncStyleMeta({
source,
style,
@ -626,24 +473,6 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer {
});
}
async _syncJoinFormatters(syncContext: DataRequestContext, join: InnerJoin, style: IVectorStyle) {
const joinSource = join.getRightJoinSource();
return this._syncFormatters({
source: joinSource,
dataRequestId: join.getSourceFormattersDataRequestId(),
fields: style
.getDynamicPropertiesArray()
.filter((dynamicStyleProp) => {
const matchingField = joinSource.getFieldByName(dynamicStyleProp.getFieldName());
return dynamicStyleProp.getFieldOrigin() === FIELD_ORIGIN.JOIN && !!matchingField;
})
.map((dynamicStyleProp) => {
return dynamicStyleProp.getField()!;
}),
...syncContext,
});
}
async _syncFormatters({
source,
dataRequestId,
@ -693,128 +522,6 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer {
}
}
async syncData(syncContext: DataRequestContext) {
await this._syncData(syncContext, this.getSource(), this.getCurrentStyle());
}
// TLDR: Do not call getSource or getCurrentStyle in syncData flow. Use 'source' and 'style' arguments instead.
//
// 1) State is contained in the redux store. Layer instance state is readonly.
// 2) Even though data request descriptor updates trigger new instances for rendering,
// syncing data executes on a single object instance. Syncing data can not use updated redux store state.
//
// Blended layer data syncing branches on the source/style depending on whether clustering is used or not.
// Given 1 above, which source/style to use can not be stored in Layer instance state.
// Given 2 above, which source/style to use can not be pulled from data request state.
// Therefore, source and style are provided as arugments and must be used instead of calling getSource or getCurrentStyle.
async _syncData(syncContext: DataRequestContext, source: IVectorSource, style: IVectorStyle) {
if (this.isLoadingBounds()) {
return;
}
try {
await this._syncSourceStyleMeta(syncContext, source, style);
await this._syncSourceFormatters(syncContext, source, style);
const sourceResult = await syncVectorSource({
layerId: this.getId(),
layerName: await this.getDisplayName(source),
prevDataRequest: this.getSourceDataRequest(),
requestMeta: await this._getVectorSourceRequestMeta(
syncContext.isForceRefresh,
syncContext.dataFilters,
source,
style
),
syncContext,
source,
getUpdateDueToTimeslice: (timeslice?: Timeslice) => {
return this._getUpdateDueToTimesliceFromSourceRequestMeta(source, timeslice);
},
});
await this._syncSupportsFeatureEditing({ syncContext, source });
if (
!sourceResult.featureCollection ||
!sourceResult.featureCollection.features.length ||
!this.hasJoins()
) {
return;
}
const joinStates = await this._syncJoins(syncContext, style);
performInnerJoins(
sourceResult,
joinStates,
syncContext.updateSourceData,
syncContext.onJoinError
);
} catch (error) {
if (!(error instanceof DataRequestAbortError)) {
throw error;
}
}
}
async _syncSupportsFeatureEditing({
syncContext,
source,
}: {
syncContext: DataRequestContext;
source: IVectorSource;
}) {
if (syncContext.dataFilters.isReadOnly) {
return;
}
const { startLoading, stopLoading, onLoadError } = syncContext;
const dataRequestId = SUPPORTS_FEATURE_EDITING_REQUEST_ID;
const requestToken = Symbol(`layer-${this.getId()}-${dataRequestId}`);
const prevDataRequest = this.getDataRequest(dataRequestId);
if (prevDataRequest) {
return;
}
try {
startLoading(dataRequestId, requestToken);
const supportsFeatureEditing = await source.supportsFeatureEditing();
stopLoading(dataRequestId, requestToken, { supportsFeatureEditing });
} catch (error) {
onLoadError(dataRequestId, requestToken, error.message);
throw error;
}
}
_getSourceFeatureCollection() {
if (this.getSource().isMvt()) {
return null;
}
const sourceDataRequest = this.getSourceDataRequest();
return sourceDataRequest ? (sourceDataRequest.getData() as FeatureCollection) : null;
}
_syncFeatureCollectionWithMb(mbMap: MbMap) {
const mbGeoJSONSource = mbMap.getSource(this.getId()) as MbGeoJSONSource;
const featureCollection = this._getSourceFeatureCollection();
const featureCollectionOnMap = AbstractLayer.getBoundDataForSource(mbMap, this.getId());
if (!featureCollection) {
if (featureCollectionOnMap) {
this.getCurrentStyle().clearFeatureState(featureCollectionOnMap, mbMap, this.getId());
}
mbGeoJSONSource.setData(EMPTY_FEATURE_COLLECTION);
return;
}
// "feature-state" data expressions are not supported with layout properties.
// To work around this limitation,
// scaled layout properties (like icon-size) must fall back to geojson property values :(
const hasGeoJsonProperties = this.getCurrentStyle().setFeatureStateAndStyleProps(
featureCollection,
mbMap,
this.getId()
);
if (featureCollection !== featureCollectionOnMap || hasGeoJsonProperties) {
mbGeoJSONSource.setData(featureCollection);
}
}
_setMbPointsProperties(
mbMap: MbMap,
mvtSourceLayer?: string,
@ -989,33 +696,6 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer {
mbMap.setLayerZoomRange(labelLayerId, this.getMinZoom(), this.getMaxZoom());
}
_syncStylePropertiesWithMb(mbMap: MbMap, timeslice?: Timeslice) {
const timesliceMaskConfig = this._getTimesliceMaskConfig(timeslice);
this._setMbLabelProperties(mbMap, undefined, timesliceMaskConfig);
this._setMbPointsProperties(mbMap, undefined, timesliceMaskConfig);
this._setMbLinePolygonProperties(mbMap, undefined, timesliceMaskConfig);
}
_getTimesliceMaskConfig(timeslice?: Timeslice): TimesliceMaskConfig | undefined {
if (!timeslice || this.hasJoins()) {
return;
}
const prevMeta = this.getSourceDataRequest()?.getMeta();
return prevMeta !== undefined && prevMeta.timesliceMaskField !== undefined
? {
timesliceMaskField: prevMeta.timesliceMaskField,
timeslice,
}
: undefined;
}
syncLayerWithMB(mbMap: MbMap, timeslice?: Timeslice) {
addGeoJsonMbSource(this._getMbSourceId(), this.getMbLayerIds(), mbMap);
this._syncFeatureCollectionWithMb(mbMap);
this._syncStylePropertiesWithMb(mbMap, timeslice);
}
_getMbPointLayerId() {
return this.makeMbLayerId('circle');
}
@ -1090,34 +770,17 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer {
}
getFeatureId(feature: Feature): string | number | undefined {
return feature.properties?.[GEOJSON_FEATURE_ID_PROPERTY_NAME];
throw new Error('Should implement AbstractVectorLayer#getFeatureId');
}
getFeatureById(id: string | number) {
const featureCollection = this._getSourceFeatureCollection();
if (!featureCollection) {
return null;
}
const targetFeature = featureCollection.features.find((feature) => {
return this.getFeatureId(feature) === id;
});
return targetFeature ? targetFeature : null;
getFeatureById(id: string | number): Feature | null {
throw new Error('Should implement AbstractVectorLayer#getFeatureById');
}
async getLicensedFeatures() {
return await this._source.getLicensedFeatures();
}
_getUpdateDueToTimesliceFromSourceRequestMeta(source: ISource, timeslice?: Timeslice) {
const prevDataRequest = this.getSourceDataRequest();
const prevMeta = prevDataRequest?.getMeta();
if (!prevMeta) {
return true;
}
return source.getUpdateDueToTimeslice(prevMeta, timeslice);
}
async addFeature(geometry: Geometry | Position[]) {
const layerSource = this.getSource();
const defaultFields = await layerSource.getDefaultFields();
@ -1130,11 +793,6 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer {
}
async getStyleMetaDescriptorFromLocalFeatures(): Promise<StyleMetaDescriptor | null> {
const sourceDataRequest = this.getSourceDataRequest();
const style = this.getCurrentStyle();
if (!style || !sourceDataRequest) {
return null;
}
return await style.pluckStyleMetaFromSourceDataRequest(sourceDataRequest);
throw new Error('Should implement AbstractVectorLayer#getStyleMetaDescriptorFromLocalFeatures');
}
}

View file

@ -7,7 +7,7 @@
import React from 'react';
import { i18n } from '@kbn/i18n';
import { VectorLayer } from '../../layers/vector_layer';
import { GeoJsonVectorLayer } from '../../layers/vector_layer';
import { LayerWizard, RenderWizardArguments } from '../../layers/layer_wizard_registry';
import { EMSFileCreateSourceEditor } from './create_source_editor';
import { EMSFileSource, getSourceTitle } from './ems_file_source';
@ -46,7 +46,7 @@ export const emsBoundariesLayerWizardConfig: LayerWizard = {
renderWizard: ({ previewLayers, mapColors }: RenderWizardArguments) => {
const onSourceConfigChange = (sourceConfig: Partial<EMSFileSourceDescriptor>) => {
const sourceDescriptor = EMSFileSource.createDescriptor(sourceConfig);
const layerDescriptor = VectorLayer.createDescriptor({ sourceDescriptor }, mapColors);
const layerDescriptor = GeoJsonVectorLayer.createDescriptor({ sourceDescriptor }, mapColors);
previewLayers([layerDescriptor]);
};
return <EMSFileCreateSourceEditor onSourceConfigChange={onSourceConfigChange} />;

View file

@ -11,7 +11,7 @@ import React from 'react';
import { CreateSourceEditor } from './create_source_editor';
import { ESGeoGridSource, clustersTitle } from './es_geo_grid_source';
import { LayerWizard, RenderWizardArguments } from '../../layers/layer_wizard_registry';
import { VectorLayer } from '../../layers/vector_layer';
import { GeoJsonVectorLayer } from '../../layers/vector_layer';
import {
ESGeoGridSourceDescriptor,
ColorDynamicOptions,
@ -45,7 +45,7 @@ export const clustersLayerWizardConfig: LayerWizard = {
}
const defaultDynamicProperties = getDefaultDynamicProperties();
const layerDescriptor = VectorLayer.createDescriptor({
const layerDescriptor = GeoJsonVectorLayer.createDescriptor({
sourceDescriptor: ESGeoGridSource.createDescriptor(sourceConfig),
style: VectorStyle.createDescriptor({
// @ts-ignore

View file

@ -12,7 +12,7 @@ import { ESGeoLineSource, geoLineTitle, REQUIRES_GOLD_LICENSE_MSG } from './es_g
import { LayerWizard, RenderWizardArguments } from '../../layers/layer_wizard_registry';
import { LAYER_WIZARD_CATEGORY, STYLE_TYPE, VECTOR_STYLES } from '../../../../common/constants';
import { VectorStyle } from '../../styles/vector/vector_style';
import { VectorLayer } from '../../layers/vector_layer';
import { GeoJsonVectorLayer } from '../../layers/vector_layer';
import { getIsGoldPlus } from '../../../licensed_features';
import { TracksLayerIcon } from '../../layers/icons/tracks_layer_icon';
@ -40,7 +40,7 @@ export const geoLineLayerWizardConfig: LayerWizard = {
return;
}
const layerDescriptor = VectorLayer.createDescriptor({
const layerDescriptor = GeoJsonVectorLayer.createDescriptor({
sourceDescriptor: ESGeoLineSource.createDescriptor(sourceConfig),
style: VectorStyle.createDescriptor({
[VECTOR_STYLES.LINE_WIDTH]: {

View file

@ -8,7 +8,7 @@
import React from 'react';
import { i18n } from '@kbn/i18n';
import { getDefaultDynamicProperties } from '../../styles/vector/vector_style_defaults';
import { VectorLayer } from '../../layers/vector_layer';
import { GeoJsonVectorLayer } from '../../layers/vector_layer';
// @ts-ignore
import { ESPewPewSource, sourceTitle } from './es_pew_pew_source';
import { VectorStyle } from '../../styles/vector/vector_style';
@ -40,7 +40,7 @@ export const point2PointLayerWizardConfig: LayerWizard = {
}
const defaultDynamicProperties = getDefaultDynamicProperties();
const layerDescriptor = VectorLayer.createDescriptor({
const layerDescriptor = GeoJsonVectorLayer.createDescriptor({
sourceDescriptor: ESPewPewSource.createDescriptor(sourceConfig),
style: VectorStyle.createDescriptor({
[VECTOR_STYLES.LINE_COLOR]: {

View file

@ -9,7 +9,7 @@ import { Query } from 'src/plugins/data/public';
import { LayerDescriptor } from '../../../../common/descriptor_types';
import { ES_GEO_FIELD_TYPE, SCALING_TYPES } from '../../../../common/constants';
import { ESSearchSource } from './es_search_source';
import { VectorLayer } from '../../layers/vector_layer';
import { GeoJsonVectorLayer } from '../../layers/vector_layer';
import { getIsGoldPlus } from '../../../licensed_features';
export interface CreateLayerDescriptorParams {
@ -37,5 +37,5 @@ export function createLayerDescriptor({
scalingType,
});
return VectorLayer.createDescriptor({ sourceDescriptor, query });
return GeoJsonVectorLayer.createDescriptor({ sourceDescriptor, query });
}

View file

@ -11,10 +11,8 @@ import React from 'react';
import { CreateSourceEditor } from './create_source_editor';
import { LayerWizard, RenderWizardArguments } from '../../layers/layer_wizard_registry';
import { ESSearchSource, sourceTitle } from './es_search_source';
import { BlendedVectorLayer } from '../../layers/blended_vector_layer/blended_vector_layer';
import { VectorLayer } from '../../layers/vector_layer';
import { BlendedVectorLayer, GeoJsonVectorLayer, MvtVectorLayer } from '../../layers/vector_layer';
import { LAYER_WIZARD_CATEGORY, SCALING_TYPES } from '../../../../common/constants';
import { TiledVectorLayer } from '../../layers/tiled_vector_layer/tiled_vector_layer';
import { DocumentsLayerIcon } from '../../layers/icons/documents_layer_icon';
import {
ESSearchSourceDescriptor,
@ -30,9 +28,9 @@ export function createDefaultLayerDescriptor(
if (sourceDescriptor.scalingType === SCALING_TYPES.CLUSTERS) {
return BlendedVectorLayer.createDescriptor({ sourceDescriptor }, mapColors);
} else if (sourceDescriptor.scalingType === SCALING_TYPES.MVT) {
return TiledVectorLayer.createDescriptor({ sourceDescriptor }, mapColors);
return MvtVectorLayer.createDescriptor({ sourceDescriptor }, mapColors);
} else {
return VectorLayer.createDescriptor({ sourceDescriptor }, mapColors);
return GeoJsonVectorLayer.createDescriptor({ sourceDescriptor }, mapColors);
}
}

View file

@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n';
import React from 'react';
import { CreateSourceEditor } from './create_source_editor';
import { LayerWizard, RenderWizardArguments } from '../../../layers/layer_wizard_registry';
import { VectorLayer } from '../../../layers/vector_layer';
import { GeoJsonVectorLayer } from '../../../layers/vector_layer';
import { LAYER_WIZARD_CATEGORY } from '../../../../../common/constants';
import { TopHitsLayerIcon } from '../../../layers/icons/top_hits_layer_icon';
import { ESSearchSourceDescriptor } from '../../../../../common/descriptor_types';
@ -30,7 +30,7 @@ export const esTopHitsLayerWizardConfig: LayerWizard = {
}
const sourceDescriptor = ESSearchSource.createDescriptor(sourceConfig);
const layerDescriptor = VectorLayer.createDescriptor({ sourceDescriptor }, mapColors);
const layerDescriptor = GeoJsonVectorLayer.createDescriptor({ sourceDescriptor }, mapColors);
previewLayers([layerDescriptor]);
};
return <CreateSourceEditor onSourceConfigChange={onSourceConfigChange} />;

View file

@ -10,7 +10,7 @@ import React from 'react';
import { MVTSingleLayerVectorSourceEditor } from './mvt_single_layer_vector_source_editor';
import { MVTSingleLayerVectorSource, sourceTitle } from './mvt_single_layer_vector_source';
import { LayerWizard, RenderWizardArguments } from '../../layers/layer_wizard_registry';
import { TiledVectorLayer } from '../../layers/tiled_vector_layer/tiled_vector_layer';
import { MvtVectorLayer } from '../../layers/vector_layer';
import { LAYER_WIZARD_CATEGORY } from '../../../../common/constants';
import { TiledSingleLayerVectorSourceSettings } from '../../../../common/descriptor_types';
import { VectorTileLayerIcon } from '../../layers/icons/vector_tile_layer_icon';
@ -24,7 +24,7 @@ export const mvtVectorSourceWizardConfig: LayerWizard = {
renderWizard: ({ previewLayers, mapColors }: RenderWizardArguments) => {
const onSourceConfigChange = (sourceConfig: TiledSingleLayerVectorSourceSettings) => {
const sourceDescriptor = MVTSingleLayerVectorSource.createDescriptor(sourceConfig);
const layerDescriptor = TiledVectorLayer.createDescriptor({ sourceDescriptor }, mapColors);
const layerDescriptor = MvtVectorLayer.createDescriptor({ sourceDescriptor }, mapColors);
previewLayers([layerDescriptor]);
};

View file

@ -50,7 +50,7 @@ import { ResizeChecker } from '../../../../../../src/plugins/kibana_utils/public
import { RenderToolTipContent } from '../../classes/tooltips/tooltip_property';
import { TileStatusTracker } from './tile_status_tracker';
import { DrawFeatureControl } from './draw_control/draw_feature_control';
import { TiledVectorLayer } from '../../classes/layers/tiled_vector_layer/tiled_vector_layer';
import { MvtVectorLayer } from '../../classes/layers/vector_layer';
import type { MapExtentState } from '../../reducers/map/types';
export interface Props {
@ -127,7 +127,7 @@ export class MbMap extends Component<Props, State> {
// This keeps track of the latest update calls, per layerId
_queryForMeta = (layer: ILayer) => {
if (this.state.mbMap && layer.isVisible() && layer.getType() === LAYER_TYPE.TILED_VECTOR) {
const mbFeatures = (layer as TiledVectorLayer).queryTileMetaFeatures(this.state.mbMap);
const mbFeatures = (layer as MvtVectorLayer).queryTileMetaFeatures(this.state.mbMap);
if (mbFeatures !== null) {
this.props.updateMetaFromTiles(layer.getId(), mbFeatures);
}

View file

@ -18,7 +18,7 @@ import {
getVisibilityToggleLabel,
} from '../action_labels';
import { ESSearchSource } from '../../../../../../classes/sources/es_search_source';
import { VectorLayer } from '../../../../../../classes/layers/vector_layer';
import { isVectorLayer, IVectorLayer } from '../../../../../../classes/layers/vector_layer';
import { SCALING_TYPES, VECTOR_SHAPE_TYPE } from '../../../../../../../common/constants';
export interface Props {
@ -67,10 +67,10 @@ export class TOCEntryActionsPopover extends Component<Props, State> {
}
async _loadFeatureEditing() {
if (!(this.props.layer instanceof VectorLayer)) {
if (!isVectorLayer(this.props.layer)) {
return;
}
const supportsFeatureEditing = this.props.layer.supportsFeatureEditing();
const supportsFeatureEditing = (this.props.layer as IVectorLayer).supportsFeatureEditing();
const isFeatureEditingEnabled = await this._getIsFeatureEditingEnabled();
if (
!this._isMounted ||
@ -83,7 +83,7 @@ export class TOCEntryActionsPopover extends Component<Props, State> {
}
async _getIsFeatureEditingEnabled(): Promise<boolean> {
const vectorLayer = this.props.layer as VectorLayer;
const vectorLayer = this.props.layer as IVectorLayer;
const layerSource = this.props.layer.getSource();
if (!(layerSource instanceof ESSearchSource)) {
return false;

View file

@ -7,8 +7,6 @@
import { LAYER_STYLE_TYPE, LAYER_TYPE, SOURCE_TYPES } from '../../common/constants';
jest.mock('../classes/layers/tiled_vector_layer/tiled_vector_layer', () => {});
jest.mock('../classes/layers/blended_vector_layer/blended_vector_layer', () => {});
jest.mock('../classes/layers/heatmap_layer', () => {});
jest.mock('../classes/layers/vector_tile_layer/vector_tile_layer', () => {});
jest.mock('../classes/joins/inner_join', () => {});

View file

@ -13,21 +13,25 @@ import type { Query } from 'src/plugins/data/common';
import { TileLayer } from '../classes/layers/tile_layer/tile_layer';
// @ts-ignore
import { VectorTileLayer } from '../classes/layers/vector_tile_layer/vector_tile_layer';
import { IVectorLayer, VectorLayer } from '../classes/layers/vector_layer';
import {
BlendedVectorLayer,
IVectorLayer,
MvtVectorLayer,
GeoJsonVectorLayer,
} from '../classes/layers/vector_layer';
import { VectorStyle } from '../classes/styles/vector/vector_style';
import { HeatmapLayer } from '../classes/layers/heatmap_layer';
import { BlendedVectorLayer } from '../classes/layers/blended_vector_layer/blended_vector_layer';
import { getTimeFilter } from '../kibana_services';
import {
getChartsPaletteServiceGetColor,
getInspectorAdapters,
} from '../reducers/non_serializable_instances';
import { TiledVectorLayer } from '../classes/layers/tiled_vector_layer/tiled_vector_layer';
import { copyPersistentState, TRACKED_LAYER_DESCRIPTOR } from '../reducers/copy_persistent_state';
import { InnerJoin } from '../classes/joins/inner_join';
import { getSourceByType } from '../classes/sources/source_registry';
import { GeoJsonFileSource } from '../classes/sources/geojson_file_source';
import {
LAYER_TYPE,
SOURCE_DATA_REQUEST_ID,
SPATIAL_FILTERS_LAYER_ID,
STYLE_TYPE,
@ -66,9 +70,9 @@ export function createLayerInstance(
const source: ISource = createSourceInstance(layerDescriptor.sourceDescriptor, inspectorAdapters);
switch (layerDescriptor.type) {
case TileLayer.type:
case LAYER_TYPE.TILE:
return new TileLayer({ layerDescriptor, source: source as ITMSSource });
case VectorLayer.type:
case LAYER_TYPE.VECTOR:
const joins: InnerJoin[] = [];
const vectorLayerDescriptor = layerDescriptor as VectorLayerDescriptor;
if (vectorLayerDescriptor.joins) {
@ -77,27 +81,27 @@ export function createLayerInstance(
joins.push(join);
});
}
return new VectorLayer({
return new GeoJsonVectorLayer({
layerDescriptor: vectorLayerDescriptor,
source: source as IVectorSource,
joins,
chartsPaletteServiceGetColor,
});
case VectorTileLayer.type:
case LAYER_TYPE.VECTOR_TILE:
return new VectorTileLayer({ layerDescriptor, source: source as ITMSSource });
case HeatmapLayer.type:
case LAYER_TYPE.HEATMAP:
return new HeatmapLayer({
layerDescriptor: layerDescriptor as HeatmapLayerDescriptor,
source: source as ESGeoGridSource,
});
case BlendedVectorLayer.type:
case LAYER_TYPE.BLENDED_VECTOR:
return new BlendedVectorLayer({
layerDescriptor: layerDescriptor as VectorLayerDescriptor,
source: source as IVectorSource,
chartsPaletteServiceGetColor,
});
case TiledVectorLayer.type:
return new TiledVectorLayer({
case LAYER_TYPE.TILED_VECTOR:
return new MvtVectorLayer({
layerDescriptor: layerDescriptor as VectorLayerDescriptor,
source: source as IVectorSource,
});
@ -266,8 +270,8 @@ export const getSpatialFiltersLayer = createSelector(
name: 'spatialFilters',
});
return new VectorLayer({
layerDescriptor: VectorLayer.createDescriptor({
return new GeoJsonVectorLayer({
layerDescriptor: GeoJsonVectorLayer.createDescriptor({
id: SPATIAL_FILTERS_LAYER_ID,
visible: settings.showSpatialFilters,
alpha: settings.spatialFiltersAlpa,