Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions x-pack/plugins/maps/common/mvt_request_body.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export function getAggsTileRequest({
encodedRequestBody,
geometryFieldName,
gridPrecision,
hasLabels,
index,
renderAs = RENDER_AS.POINT,
x,
Expand All @@ -30,6 +31,7 @@ export function getAggsTileRequest({
encodedRequestBody: string;
geometryFieldName: string;
gridPrecision: number;
hasLabels: boolean;
index: string;
renderAs: RENDER_AS;
x: number;
Expand All @@ -50,20 +52,23 @@ export function getAggsTileRequest({
aggs: requestBody.aggs,
fields: requestBody.fields,
runtime_mappings: requestBody.runtime_mappings,
with_labels: hasLabels,
},
};
}

export function getHitsTileRequest({
encodedRequestBody,
geometryFieldName,
hasLabels,
index,
x,
y,
z,
}: {
encodedRequestBody: string;
geometryFieldName: string;
hasLabels: boolean;
index: string;
x: number;
y: number;
Expand All @@ -86,6 +91,7 @@ export function getHitsTileRequest({
),
runtime_mappings: requestBody.runtime_mappings,
track_total_hits: typeof requestBody.size === 'number' ? requestBody.size + 1 : false,
with_labels: hasLabels,
},
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export class HeatmapLayer extends AbstractLayer {

async syncData(syncContext: DataRequestContext) {
await syncMvtSourceData({
hasLabels: false,
layerId: this.getId(),
layerName: await this.getDisplayName(),
prevDataRequest: this.getSourceDataRequest(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ describe('syncMvtSourceData', () => {
const syncContext = new MockSyncContext({ dataFilters: {} });

await syncMvtSourceData({
hasLabels: false,
layerId: 'layer1',
layerName: 'my layer',
prevDataRequest: undefined,
Expand Down Expand Up @@ -99,6 +100,7 @@ describe('syncMvtSourceData', () => {
};

await syncMvtSourceData({
hasLabels: false,
layerId: 'layer1',
layerName: 'my layer',
prevDataRequest: {
Expand Down Expand Up @@ -142,6 +144,7 @@ describe('syncMvtSourceData', () => {
};

await syncMvtSourceData({
hasLabels: false,
layerId: 'layer1',
layerName: 'my layer',
prevDataRequest: {
Expand Down Expand Up @@ -182,6 +185,7 @@ describe('syncMvtSourceData', () => {
};

await syncMvtSourceData({
hasLabels: false,
layerId: 'layer1',
layerName: 'my layer',
prevDataRequest: {
Expand Down Expand Up @@ -230,6 +234,7 @@ describe('syncMvtSourceData', () => {
};

await syncMvtSourceData({
hasLabels: false,
layerId: 'layer1',
layerName: 'my layer',
prevDataRequest: {
Expand Down Expand Up @@ -270,6 +275,7 @@ describe('syncMvtSourceData', () => {
};

await syncMvtSourceData({
hasLabels: false,
layerId: 'layer1',
layerName: 'my layer',
prevDataRequest: {
Expand Down Expand Up @@ -310,6 +316,7 @@ describe('syncMvtSourceData', () => {
};

await syncMvtSourceData({
hasLabels: false,
layerId: 'layer1',
layerName: 'my layer',
prevDataRequest: {
Expand Down Expand Up @@ -340,6 +347,7 @@ describe('syncMvtSourceData', () => {
const syncContext = new MockSyncContext({ dataFilters: {} });

await syncMvtSourceData({
hasLabels: false,
layerId: 'layer1',
layerName: 'my layer',
prevDataRequest: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ export interface MvtSourceData {
}

export async function syncMvtSourceData({
hasLabels,
layerId,
layerName,
prevDataRequest,
requestMeta,
source,
syncContext,
}: {
hasLabels: boolean;
layerId: string;
layerName: string;
prevDataRequest: DataRequest | undefined;
Expand Down Expand Up @@ -72,7 +74,7 @@ export async function syncMvtSourceData({
? uuid()
: prevData.refreshToken;

const tileUrl = await source.getTileUrl(requestMeta, refreshToken);
const tileUrl = await source.getTileUrl(requestMeta, refreshToken, hasLabels);
if (source.isESSource()) {
syncContext.inspectorAdapters.vectorTiles.addLayer(layerId, layerName, tileUrl);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ export class MvtVectorLayer extends AbstractVectorLayer {
await this._syncSupportsFeatureEditing({ syncContext, source: this.getSource() });

await syncMvtSourceData({
hasLabels: this.getCurrentStyle().hasLabels(),
layerId: this.getId(),
layerName: await this.getDisplayName(),
prevDataRequest: this.getSourceDataRequest(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,10 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer {
}
}

const isSourceGeoJson = !this.getSource().isMvt();
const filterExpr = getPointFilterExpression(
isSourceGeoJson,
this.getSource().isESSource(),
this._getJoinFilterExpression(),
timesliceMaskConfig
);
Expand Down Expand Up @@ -843,6 +846,7 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer {
const isSourceGeoJson = !this.getSource().isMvt();
const filterExpr = getLabelFilterExpression(
isSourceGeoJson,
this.getSource().isESSource(),
this._getJoinFilterExpression(),
timesliceMaskConfig
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,10 @@ describe('ESGeoGridSource', () => {
});

it('getTileUrl', async () => {
const tileUrl = await mvtGeogridSource.getTileUrl(vectorSourceRequestMeta, '1234');
const tileUrl = await mvtGeogridSource.getTileUrl(vectorSourceRequestMeta, '1234', false);

expect(tileUrl).toEqual(
"rootdir/api/maps/mvt/getGridTile/{z}/{x}/{y}.pbf?geometryFieldName=bar&index=undefined&gridPrecision=8&requestBody=(foobar%3AES_DSL_PLACEHOLDER%2Cparams%3A('0'%3A('0'%3Aindex%2C'1'%3A(fields%3A()))%2C'1'%3A('0'%3Asize%2C'1'%3A0)%2C'2'%3A('0'%3Afilter%2C'1'%3A!())%2C'3'%3A('0'%3Aquery)%2C'4'%3A('0'%3Aindex%2C'1'%3A(fields%3A()))%2C'5'%3A('0'%3Aquery%2C'1'%3A(language%3AKQL%2Cquery%3A''))%2C'6'%3A('0'%3Aaggs%2C'1'%3A())))&renderAs=heatmap&token=1234"
"rootdir/api/maps/mvt/getGridTile/{z}/{x}/{y}.pbf?geometryFieldName=bar&index=undefined&gridPrecision=8&hasLabels=false&requestBody=(foobar%3AES_DSL_PLACEHOLDER%2Cparams%3A('0'%3A('0'%3Aindex%2C'1'%3A(fields%3A()))%2C'1'%3A('0'%3Asize%2C'1'%3A0)%2C'2'%3A('0'%3Afilter%2C'1'%3A!())%2C'3'%3A('0'%3Aquery)%2C'4'%3A('0'%3Aindex%2C'1'%3A(fields%3A()))%2C'5'%3A('0'%3Aquery%2C'1'%3A(language%3AKQL%2Cquery%3A''))%2C'6'%3A('0'%3Aaggs%2C'1'%3A())))&renderAs=heatmap&token=1234"
);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,11 @@ export class ESGeoGridSource extends AbstractESAggSource implements IMvtVectorSo
return 'aggs';
}

async getTileUrl(searchFilters: VectorSourceRequestMeta, refreshToken: string): Promise<string> {
async getTileUrl(
searchFilters: VectorSourceRequestMeta,
refreshToken: string,
hasLabels: boolean
): Promise<string> {
const indexPattern = await this.getIndexPattern();
const searchSource = await this.makeSearchSource(searchFilters, 0);
searchSource.setField('aggs', this.getValueAggsDsl(indexPattern));
Expand All @@ -484,6 +488,7 @@ export class ESGeoGridSource extends AbstractESAggSource implements IMvtVectorSo
?geometryFieldName=${this._descriptor.geoField}\
&index=${indexPattern.title}\
&gridPrecision=${this._getGeoGridPrecisionResolutionDelta()}\
&hasLabels=${hasLabels}\
&requestBody=${encodeMvtResponseBody(searchSource.getSearchRequestBody())}\
&renderAs=${this._descriptor.requestType}\
&token=${refreshToken}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ describe('ESSearchSource', () => {
geoField: geoFieldName,
indexPatternId: 'ipId',
});
const tileUrl = await esSearchSource.getTileUrl(searchFilters, '1234');
const tileUrl = await esSearchSource.getTileUrl(searchFilters, '1234', false);
expect(tileUrl).toBe(
`rootdir/api/maps/mvt/getTile/{z}/{x}/{y}.pbf?geometryFieldName=bar&index=foobar-title-*&requestBody=(foobar%3AES_DSL_PLACEHOLDER%2Cparams%3A('0'%3A('0'%3Aindex%2C'1'%3A(fields%3A()%2Ctitle%3A'foobar-title-*'))%2C'1'%3A('0'%3Asize%2C'1'%3A1000)%2C'2'%3A('0'%3Afilter%2C'1'%3A!())%2C'3'%3A('0'%3Aquery)%2C'4'%3A('0'%3Aindex%2C'1'%3A(fields%3A()%2Ctitle%3A'foobar-title-*'))%2C'5'%3A('0'%3Aquery%2C'1'%3A(language%3AKQL%2Cquery%3A'tooltipField%3A%20foobar'))%2C'6'%3A('0'%3AfieldsFromSource%2C'1'%3A!(tooltipField%2CstyleField))%2C'7'%3A('0'%3Asource%2C'1'%3A!(tooltipField%2CstyleField))))&token=1234`
`rootdir/api/maps/mvt/getTile/{z}/{x}/{y}.pbf?geometryFieldName=bar&index=foobar-title-*&hasLabels=false&requestBody=(foobar%3AES_DSL_PLACEHOLDER%2Cparams%3A('0'%3A('0'%3Aindex%2C'1'%3A(fields%3A()%2Ctitle%3A'foobar-title-*'))%2C'1'%3A('0'%3Asize%2C'1'%3A1000)%2C'2'%3A('0'%3Afilter%2C'1'%3A!())%2C'3'%3A('0'%3Aquery)%2C'4'%3A('0'%3Aindex%2C'1'%3A(fields%3A()%2Ctitle%3A'foobar-title-*'))%2C'5'%3A('0'%3Aquery%2C'1'%3A(language%3AKQL%2Cquery%3A'tooltipField%3A%20foobar'))%2C'6'%3A('0'%3AfieldsFromSource%2C'1'%3A!(tooltipField%2CstyleField))%2C'7'%3A('0'%3Asource%2C'1'%3A!(tooltipField%2CstyleField))))&token=1234`
);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,11 @@ export class ESSearchSource extends AbstractESSource implements IMvtVectorSource
return 'hits';
}

async getTileUrl(searchFilters: VectorSourceRequestMeta, refreshToken: string): Promise<string> {
async getTileUrl(
searchFilters: VectorSourceRequestMeta,
refreshToken: string,
hasLabels: boolean
): Promise<string> {
const indexPattern = await this.getIndexPattern();
const indexSettings = await loadIndexSettings(indexPattern.title);

Expand Down Expand Up @@ -847,6 +851,7 @@ export class ESSearchSource extends AbstractESSource implements IMvtVectorSource
return `${mvtUrlServicePath}\
?geometryFieldName=${this._descriptor.geoField}\
&index=${indexPattern.title}\
&hasLabels=${hasLabels}\
&requestBody=${encodeMvtResponseBody(searchSource.getSearchRequestBody())}\
&token=${refreshToken}`;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ export interface IMvtVectorSource extends IVectorSource {
* IMvtVectorSource.getTileUrl returns the tile source URL.
* Append refreshToken as a URL parameter to force tile re-fetch on refresh (not required)
*/
getTileUrl(searchFilters: VectorSourceRequestMeta, refreshToken: string): Promise<string>;
getTileUrl(
searchFilters: VectorSourceRequestMeta,
refreshToken: string,
hasLabels: boolean
): Promise<string>;

/*
* Tile vector sources can contain multiple layers. For example, elasticsearch _mvt tiles contain the layers "hits", "aggs", and "meta".
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ export function makeMbClampedNumberExpression({
];
}

export function getHasLabel(label: StaticTextProperty | DynamicTextProperty) {
export function getHasLabel(label: StaticTextProperty | DynamicTextProperty): boolean {
return label.isDynamic()
? label.isComplete()
: (label as StaticTextProperty).getOptions().value != null &&
(label as StaticTextProperty).getOptions().value.length;
(label as StaticTextProperty).getOptions().value.length > 0;
}
14 changes: 12 additions & 2 deletions x-pack/plugins/maps/public/classes/styles/vector/vector_style.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ export interface IVectorStyle extends IStyle {
mbMap: MbMap,
mbSourceId: string
) => boolean;

/*
* Returns true when "Label" style configuration is complete and map shows a label for layer features.
*/
hasLabels: () => boolean;

arePointsSymbolizedAsCircles: () => boolean;
setMBPaintProperties: ({
alpha,
Expand Down Expand Up @@ -674,14 +680,14 @@ export class VectorStyle implements IVectorStyle {
}

_getLegendDetailStyleProperties = () => {
const hasLabel = getHasLabel(this._labelStyleProperty);
const hasLabels = this.hasLabels();
return this.getDynamicPropertiesArray().filter((styleProperty) => {
const styleName = styleProperty.getStyleName();
if ([VECTOR_STYLES.ICON_ORIENTATION, VECTOR_STYLES.LABEL_TEXT].includes(styleName)) {
return false;
}

if (!hasLabel && LABEL_STYLES.includes(styleName)) {
if (!hasLabels && LABEL_STYLES.includes(styleName)) {
// do not render legend for label styles when there is no label
return false;
}
Expand Down Expand Up @@ -768,6 +774,10 @@ export class VectorStyle implements IVectorStyle {
return !this._symbolizeAsStyleProperty.isSymbolizedAsIcon();
}

hasLabels() {
return getHasLabel(this._labelStyleProperty);
}

setMBPaintProperties({
alpha,
mbMap,
Expand Down
23 changes: 16 additions & 7 deletions x-pack/plugins/maps/public/classes/util/mb_filter_expressions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export function getFillFilterExpression(
): FilterSpecification {
return getFilterExpression(
[
// explicit EXCLUDE_CENTROID_FEATURES filter not needed. Centroids are points and are filtered out by geometry narrowing
// explicit "exclude centroid features" filter not needed. Label features are points and are filtered out by geometry narrowing
[
'any',
['==', ['geometry-type'], GEO_JSON_TYPE.POLYGON],
Expand All @@ -73,7 +73,7 @@ export function getLineFilterExpression(
): FilterSpecification {
return getFilterExpression(
[
// explicit EXCLUDE_CENTROID_FEATURES filter not needed. Centroids are points and are filtered out by geometry narrowing
// explicit "exclude centroid features" filter not needed. Label features are points and are filtered out by geometry narrowing
[
'any',
['==', ['geometry-type'], GEO_JSON_TYPE.POLYGON],
Expand All @@ -94,18 +94,25 @@ const IS_POINT_FEATURE = [
];

export function getPointFilterExpression(
isSourceGeoJson: boolean,
isESSource: boolean,
joinFilter?: FilterSpecification,
timesliceMaskConfig?: TimesliceMaskConfig
): FilterSpecification {
return getFilterExpression(
[EXCLUDE_CENTROID_FEATURES, IS_POINT_FEATURE],
joinFilter,
timesliceMaskConfig
);
const filters: FilterSpecification[] = [];
if (isSourceGeoJson) {
filters.push(EXCLUDE_CENTROID_FEATURES);
} else if (!isSourceGeoJson && isESSource) {
filters.push(['!=', ['get', '_mvt_label_position'], true]);
}
filters.push(IS_POINT_FEATURE);

return getFilterExpression(filters, joinFilter, timesliceMaskConfig);
}

export function getLabelFilterExpression(
isSourceGeoJson: boolean,
isESSource: boolean,
joinFilter?: FilterSpecification,
timesliceMaskConfig?: TimesliceMaskConfig
): FilterSpecification {
Expand All @@ -116,6 +123,8 @@ export function getLabelFilterExpression(
// For GeoJSON sources, show label for centroid features or point/multi-point features only.
// no explicit isCentroidFeature filter is needed, centroids are points and are included in the geometry filter.
filters.push(IS_POINT_FEATURE);
} else if (!isSourceGeoJson && isESSource) {
filters.push(['==', ['get', '_mvt_label_position'], true]);
}

return getFilterExpression(filters, joinFilter, timesliceMaskConfig);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ test('Should return elasticsearch vector tile request for aggs tiles', () => {
expect(
getTileRequest({
layerId: '1',
tileUrl: `/pof/api/maps/mvt/getGridTile/{z}/{x}/{y}.pbf?geometryFieldName=geo.coordinates&index=kibana_sample_data_logs&gridPrecision=8&requestBody=(_source%3A(excludes%3A!())%2Caggs%3A()%2Cfields%3A!((field%3A'%40timestamp'%2Cformat%3Adate_time)%2C(field%3Atimestamp%2Cformat%3Adate_time)%2C(field%3Autc_time%2Cformat%3Adate_time))%2Cquery%3A(bool%3A(filter%3A!((match_phrase%3A(machine.os.keyword%3Aios))%2C(range%3A(timestamp%3A(format%3Astrict_date_optional_time%2Cgte%3A'2022-04-22T16%3A46%3A00.744Z'%2Clte%3A'2022-04-29T16%3A46%3A05.345Z'))))%2Cmust%3A!()%2Cmust_not%3A!()%2Cshould%3A!()))%2Cruntime_mappings%3A(hour_of_day%3A(script%3A(source%3A'emit(doc%5B!'timestamp!'%5D.value.getHour())%3B')%2Ctype%3Along))%2Cscript_fields%3A()%2Csize%3A0%2Cstored_fields%3A!('*'))&renderAs=heatmap&token=e8bff005-ccea-464a-ae56-2061b4f8ce68`,
tileUrl: `/pof/api/maps/mvt/getGridTile/{z}/{x}/{y}.pbf?geometryFieldName=geo.coordinates&hasLabels=false&index=kibana_sample_data_logs&gridPrecision=8&requestBody=(_source%3A(excludes%3A!())%2Caggs%3A()%2Cfields%3A!((field%3A'%40timestamp'%2Cformat%3Adate_time)%2C(field%3Atimestamp%2Cformat%3Adate_time)%2C(field%3Autc_time%2Cformat%3Adate_time))%2Cquery%3A(bool%3A(filter%3A!((match_phrase%3A(machine.os.keyword%3Aios))%2C(range%3A(timestamp%3A(format%3Astrict_date_optional_time%2Cgte%3A'2022-04-22T16%3A46%3A00.744Z'%2Clte%3A'2022-04-29T16%3A46%3A05.345Z'))))%2Cmust%3A!()%2Cmust_not%3A!()%2Cshould%3A!()))%2Cruntime_mappings%3A(hour_of_day%3A(script%3A(source%3A'emit(doc%5B!'timestamp!'%5D.value.getHour())%3B')%2Ctype%3Along))%2Cscript_fields%3A()%2Csize%3A0%2Cstored_fields%3A!('*'))&renderAs=heatmap&token=e8bff005-ccea-464a-ae56-2061b4f8ce68`,
x: 3,
y: 0,
z: 2,
Expand Down Expand Up @@ -71,6 +71,7 @@ test('Should return elasticsearch vector tile request for aggs tiles', () => {
type: 'long',
},
},
with_labels: false,
},
});
});
Expand All @@ -79,7 +80,7 @@ test('Should return elasticsearch vector tile request for hits tiles', () => {
expect(
getTileRequest({
layerId: '1',
tileUrl: `http://localhost:5601/pof/api/maps/mvt/getTile/{z}/{x}/{y}.pbf?geometryFieldName=geo.coordinates&index=kibana_sample_data_logs&requestBody=(_source%3A!f%2Cdocvalue_fields%3A!()%2Cquery%3A(bool%3A(filter%3A!((range%3A(timestamp%3A(format%3Astrict_date_optional_time%2Cgte%3A%272022-04-22T16%3A46%3A00.744Z%27%2Clte%3A%272022-04-29T16%3A46%3A05.345Z%27))))%2Cmust%3A!()%2Cmust_not%3A!()%2Cshould%3A!()))%2Cruntime_mappings%3A(hour_of_day%3A(script%3A(source%3A%27emit(doc%5B!%27timestamp!%27%5D.value.getHour())%3B%27)%2Ctype%3Along))%2Cscript_fields%3A()%2Csize%3A10000%2Cstored_fields%3A!(geo.coordinates))&token=415049b6-bb0a-444a-a7b9-89717db5183c`,
tileUrl: `http://localhost:5601/pof/api/maps/mvt/getTile/{z}/{x}/{y}.pbf?geometryFieldName=geo.coordinates&hasLabels=true&index=kibana_sample_data_logs&requestBody=(_source%3A!f%2Cdocvalue_fields%3A!()%2Cquery%3A(bool%3A(filter%3A!((range%3A(timestamp%3A(format%3Astrict_date_optional_time%2Cgte%3A%272022-04-22T16%3A46%3A00.744Z%27%2Clte%3A%272022-04-29T16%3A46%3A05.345Z%27))))%2Cmust%3A!()%2Cmust_not%3A!()%2Cshould%3A!()))%2Cruntime_mappings%3A(hour_of_day%3A(script%3A(source%3A%27emit(doc%5B!%27timestamp!%27%5D.value.getHour())%3B%27)%2Ctype%3Along))%2Cscript_fields%3A()%2Csize%3A10000%2Cstored_fields%3A!(geo.coordinates))&token=415049b6-bb0a-444a-a7b9-89717db5183c`,
x: 0,
y: 0,
z: 2,
Expand Down Expand Up @@ -118,6 +119,7 @@ test('Should return elasticsearch vector tile request for hits tiles', () => {
},
},
track_total_hits: 10001,
with_labels: true,
},
});
});
Loading