[Maps] use geo-tile aggregation instead of geohash precision (#29776)

This commit is contained in:
Thomas Neirynck 2019-02-05 13:01:10 -05:00 committed by GitHub
parent cdf3266f23
commit 3ccf6793df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 292 additions and 169 deletions

View file

@ -0,0 +1,63 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import _ from 'lodash';
import { BucketAggType } from './_bucket_agg_type';
import { i18n } from '@kbn/i18n';
export const geoTileBucketAgg = new BucketAggType({
name: 'geotile_grid',
title: i18n.translate('common.ui.aggTypes.buckets.geotileGridTitle', {
defaultMessage: 'Geotile',
}),
params: [
{
name: 'field',
type: 'field',
filterFieldTypes: 'geo_point'
},
{
name: 'useGeocentroid',
default: true,
write: _.noop
},
{
name: 'precision',
default: 0,
}
],
getRequestAggs: function (agg) {
const aggs = [];
const params = agg.params;
aggs.push(agg);
if (params.useGeocentroid) {
aggs.push(agg.aggConfigs.createAggConfig({
type: 'geo_centroid',
enabled: true,
params: {
field: agg.getField()
}
}, { addToAggConfigs: false }));
}
return aggs;
}
});

View file

@ -47,6 +47,7 @@ import { filterBucketAgg } from './buckets/filter';
import { filtersBucketAgg } from './buckets/filters';
import { significantTermsBucketAgg } from './buckets/significant_terms';
import { geoHashBucketAgg } from './buckets/geo_hash';
import { geoTileBucketAgg } from './buckets/geo_tile';
import { bucketSumMetricAgg } from './metrics/bucket_sum';
import { bucketAvgMetricAgg } from './metrics/bucket_avg';
import { bucketMinMetricAgg } from './metrics/bucket_min';
@ -86,7 +87,8 @@ const aggs = {
filterBucketAgg,
filtersBucketAgg,
significantTermsBucketAgg,
geoHashBucketAgg
geoHashBucketAgg,
geoTileBucketAgg,
]
};

View file

@ -99,23 +99,6 @@ export function geoPointToGeometry(value) {
);
}
export function makeGeohashGridPolygon(geohashGridFeature) {
const esBbox = geohashGridFeature.properties.geohash_meta.rectangle;
return {
type: 'Polygon',
coordinates: [
[
[esBbox[0][1], esBbox[0][0]],
[esBbox[1][1], esBbox[1][0]],
[esBbox[2][1], esBbox[2][0]],
[esBbox[3][1], esBbox[3][0]],
[esBbox[0][1], esBbox[0][0]],
]
]
};
}
export function geoShapeToGeometry(value) {
if (!value) {
return [];

View file

@ -4,116 +4,101 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { decodeGeoHash } from 'ui/utils/decode_geo_hash';
import { gridDimensions } from 'ui/vis/map/grid_dimensions';
import { RENDER_AS } from './render_as';
import { getTileBoundingBox } from './geo_tile_utils';
/*
* Fork of ui/public/vis/map/convert_to_geojson.js that supports multiple metrics
*/
export function convertToGeoJson(tabifiedResponse) {
const EMPTY_FEATURE_COLLECTION = {
type: 'FeatureCollection',
features: []
};
let features;
const min = Infinity;
const max = -Infinity;
let geoAgg;
export function convertToGeoJson({ table, renderAs }) {
if (tabifiedResponse && tabifiedResponse.rows) {
const table = tabifiedResponse;
const geohashColumn = table.columns.find(column => column.aggConfig.type.dslName === 'geohash_grid');
if (!geohashColumn) {
features = [];
} else {
geoAgg = geohashColumn.aggConfig;
const metricColumns = table.columns.filter(column => {
return column.aggConfig.type.type === 'metrics'
&& column.aggConfig.type.dslName !== 'geo_centroid';
});
const geocentroidColumn = table.columns.find(column => column.aggConfig.type.dslName === 'geo_centroid');
features = table.rows.map(row => {
const geohash = row[geohashColumn.id];
if (!geohash) return false;
const geohashLocation = decodeGeoHash(geohash);
let pointCoordinates;
if (geocentroidColumn) {
const location = row[geocentroidColumn.id];
pointCoordinates = [location.lon, location.lat];
} else {
pointCoordinates = [geohashLocation.longitude[2], geohashLocation.latitude[2]];
}
const rectangle = [
[geohashLocation.latitude[0], geohashLocation.longitude[0]],
[geohashLocation.latitude[0], geohashLocation.longitude[1]],
[geohashLocation.latitude[1], geohashLocation.longitude[1]],
[geohashLocation.latitude[1], geohashLocation.longitude[0]],
];
const centerLatLng = [
geohashLocation.latitude[2],
geohashLocation.longitude[2]
];
if (geoAgg.params.useGeocentroid) {
// see https://github.com/elastic/elasticsearch/issues/24694 for why clampGrid is used
pointCoordinates[0] = clampGrid(pointCoordinates[0], geohashLocation.longitude[0], geohashLocation.longitude[1]);
pointCoordinates[1] = clampGrid(pointCoordinates[1], geohashLocation.latitude[0], geohashLocation.latitude[1]);
}
const metrics = {};
metricColumns.forEach(metricColumn => {
metrics[metricColumn.aggConfig.id] = row[metricColumn.id];
});
//const value = row[metricColumn.id];
//min = Math.min(min, value);
//max = Math.max(max, value);
return {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: pointCoordinates
},
properties: {
geohash: geohash,
geohash_meta: {
center: centerLatLng,
rectangle: rectangle
},
...metrics
}
};
}).filter(row => row);
}
} else {
features = [];
if (!table || !table.rows) {
return EMPTY_FEATURE_COLLECTION;
}
const featureCollection = {
type: 'FeatureCollection',
features: features
};
const geoGridColumn = table.columns.find(column => column.aggConfig.type.dslName === 'geotile_grid');
if (!geoGridColumn) {
return EMPTY_FEATURE_COLLECTION;
}
const metricColumns = table.columns.filter(column => {
return column.aggConfig.type.type === 'metrics'
&& column.aggConfig.type.dslName !== 'geo_centroid';
});
const geocentroidColumn = table.columns.find(column => column.aggConfig.type.dslName === 'geo_centroid');
if (!geocentroidColumn) {
return EMPTY_FEATURE_COLLECTION;
}
const features = [];
table.rows.forEach(row => {
const gridKey = row[geoGridColumn.id];
if (!gridKey) {
return;
}
const properties = {};
metricColumns.forEach(metricColumn => {
properties[metricColumn.aggConfig.id] = row[metricColumn.id];
});
features.push({
type: 'Feature',
geometry: rowToGeometry({
row,
gridKey,
geocentroidColumn,
renderAs,
}),
properties
});
});
return {
featureCollection: featureCollection,
meta: {
min: min,
max: max,
geohashGridDimensionsAtEquator: geoAgg && gridDimensions(geoAgg.params.precision)
featureCollection: {
type: 'FeatureCollection',
features: features
}
};
}
function rowToGeometry({
row,
gridKey,
geocentroidColumn,
renderAs,
}) {
const { top, bottom, right, left } = getTileBoundingBox(gridKey);
if (renderAs === RENDER_AS.GRID) {
return {
type: 'Polygon',
coordinates: [
[
[right, top],
[left, top],
[left, bottom],
[right, bottom],
[right, top],
]
]
};
}
// see https://github.com/elastic/elasticsearch/issues/24694 for why clampGrid is used
const pointCoordinates = [
clampGrid(row[geocentroidColumn.id].lon, left, right),
clampGrid(row[geocentroidColumn.id].lat, bottom, top)
];
return {
type: 'Point',
coordinates: pointCoordinates
};
}
function clampGrid(val, min, max) {
if (val > max) val = max;
else if (val < min) val = min;

View file

@ -12,7 +12,6 @@ import { AbstractESSource } from '../es_source';
import { HeatmapLayer } from '../../heatmap_layer';
import { VectorLayer } from '../../vector_layer';
import { Schemas } from 'ui/vis/editors/default/schemas';
import { makeGeohashGridPolygon } from '../../../../elasticsearch_geo_utils';
import { AggConfigs } from 'ui/vis/agg_configs';
import { tabifyAggResponse } from 'ui/agg_response/tabify';
import { convertToGeoJson } from './convert_to_geojson';
@ -21,10 +20,10 @@ import { RENDER_AS } from './render_as';
import { CreateSourceEditor } from './create_source_editor';
import { UpdateSourceEditor } from './update_source_editor';
import { GRID_RESOLUTION } from '../../grid_resolution';
import { getGeohashPrecisionForZoom } from './zoom_to_precision';
const COUNT_PROP_LABEL = 'Count';
const COUNT_PROP_NAME = 'doc_count';
const MAX_GEOTILE_LEVEL = 29;
const aggSchemas = new Schemas([
{
@ -41,8 +40,8 @@ const aggSchemas = new Schemas([
{
group: 'buckets',
name: 'segment',
title: 'Geo Coordinates',
aggFilter: 'geohash_grid',
title: 'Geo Grid',
aggFilter: 'geotile_grid',
min: 1,
max: 1
}
@ -119,20 +118,21 @@ export class ESGeoGridSource extends AbstractESSource {
}
getGeoGridPrecision(zoom) {
return getGeohashPrecisionForZoom(zoom) + this._getGeoGridPrecisionResolutionDelta();
const targetGeotileLevel = Math.ceil(zoom) + this._getGeoGridPrecisionResolutionDelta();
return Math.min(targetGeotileLevel, MAX_GEOTILE_LEVEL);
}
_getGeoGridPrecisionResolutionDelta() {
if (this._descriptor.resolution === GRID_RESOLUTION.COARSE) {
return 0;
return 2;
}
if (this._descriptor.resolution === GRID_RESOLUTION.FINE) {
return 1;
return 3;
}
if (this._descriptor.resolution === GRID_RESOLUTION.MOST_FINE) {
return 2;
return 4;
}
throw new Error(`Grid resolution param not recognized: ${this._descriptor.resolution}`);
@ -147,13 +147,6 @@ export class ESGeoGridSource extends AbstractESSource {
query: searchFilters.query,
});
if (this._descriptor.requestType === RENDER_AS.GRID) {
featureCollection.features.forEach((feature) => {
//replace geometries with the polygon
feature.geometry = makeGeohashGridPolygon(feature);
});
}
return {
data: featureCollection,
meta: {
@ -168,7 +161,6 @@ export class ESGeoGridSource extends AbstractESSource {
});
}
async getGeoJsonPoints({ layerName }, { geogridPrecision, buffer, timeFilters, query }) {
const indexPattern = await this._getIndexPattern();
@ -178,7 +170,10 @@ export class ESGeoGridSource extends AbstractESSource {
const esResponse = await this._runEsQuery(layerName, searchSource, 'Elasticsearch geohash_grid aggregation request');
const tabifiedResp = tabifyAggResponse(aggConfigs, esResponse);
const { featureCollection } = convertToGeoJson(tabifiedResp);
const { featureCollection } = convertToGeoJson({
table: tabifiedResp,
renderAs: this._descriptor.requestType,
});
return featureCollection;
}
@ -234,16 +229,14 @@ export class ESGeoGridSource extends AbstractESSource {
{
id: 'grid',
enabled: true,
type: 'geohash_grid',
type: 'geotile_grid',
schema: 'segment',
params: {
field: this._descriptor.geoField,
isFilteredByCollar: false, // map extent filter is in query so no need to filter in aggregation
useGeocentroid: true, // TODO make configurable
autoPrecision: false, // false so we can define our own precision levels based on styling
useGeocentroid: true,
precision: precision,
}
}
},
];
}

View file

@ -0,0 +1,60 @@
/*
* 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 _ from 'lodash';
import { DECIMAL_DEGREES_PRECISION } from '../../../../../common/constants';
const ZOOM_TILE_KEY_INDEX = 0;
const X_TILE_KEY_INDEX = 1;
const Y_TILE_KEY_INDEX = 2;
export function parseTileKey(tileKey) {
const tileKeyParts = tileKey.split('/');
if (tileKeyParts.length !== 3) {
throw new Error(`Invalid tile key, expecting "zoom/x/y" format but got ${tileKey}`);
}
const zoom = parseInt(tileKeyParts[ZOOM_TILE_KEY_INDEX], 10);
const x = parseInt(tileKeyParts[X_TILE_KEY_INDEX], 10);
const y = parseInt(tileKeyParts[Y_TILE_KEY_INDEX], 10);
const tileCount = Math.pow(2, zoom);
if (x >= tileCount) {
throw new Error(`Tile key is malformed, expected x to be less than ${tileCount}, you provided ${x}`);
}
if (y >= tileCount) {
throw new Error(`Tile key is malformed, expected y to be less than ${tileCount}, you provided ${y}`);
}
return { x, y, zoom, tileCount };
}
function sinh(x) {
return (Math.exp(x) - Math.exp(-x)) / 2;
}
function tileToLatitude(y, tileCount) {
const radians = Math.atan(sinh(Math.PI - (2 * Math.PI * y / tileCount)));
const lat = 180 / Math.PI * radians;
return _.round(lat, DECIMAL_DEGREES_PRECISION);
}
function tileToLongitude(x, tileCount) {
const lon = (x / tileCount * 360) - 180;
return _.round(lon, DECIMAL_DEGREES_PRECISION);
}
export function getTileBoundingBox(tileKey) {
const { x, y, tileCount } = parseTileKey(tileKey);
return {
top: tileToLatitude(y, tileCount),
bottom: tileToLatitude(y + 1, tileCount),
left: tileToLongitude(x, tileCount),
right: tileToLongitude(x + 1, tileCount),
};
}

View file

@ -0,0 +1,26 @@
/*
* 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 { parseTileKey, getTileBoundingBox } from './geo_tile_utils';
it('Should parse tile key', () => {
expect(parseTileKey('15/23423/1867')).toEqual({
zoom: 15,
x: 23423,
y: 1867,
tileCount: Math.pow(2, 15)
});
});
it('Should convert tile key to geojson Polygon', () => {
const geometry = getTileBoundingBox('15/23423/1867');
expect(geometry).toEqual({
top: 82.92546,
bottom: 82.92411,
right: 77.34375,
left: 77.33276
});
});

View file

@ -55,7 +55,6 @@ export class UpdateSourceEditor extends Component {
};
_renderMetricsEditor() {
const metricsFilter = (this.props.renderAs === RENDER_AS.HEATMAP) ? ((metric) => {
//these are countable metrics, where blending heatmap color blobs make sense
return ['count', 'sum'].includes(metric.value);

View file

@ -21,10 +21,9 @@ const NO_TILEMAP_LAYER_MSG =
export class CreateSourceEditor extends Component {
state = {
url: null
}
};
_loadUrl = async () => {
const tilemap = await getKibanaTileMap();
@ -32,9 +31,9 @@ export class CreateSourceEditor extends Component {
this.setState({
url: tilemap.url
});
this.props.previewTilemap(this.props.url);
this.props.previewTilemap(this.state.url);
}
}
};
componentWillUnmount() {
this._isMounted = false;

View file

@ -42,11 +42,11 @@ export class HeatmapStyle {
setMBPaintProperties({ alpha, mbMap, layerId, propertyName, resolution }) {
let radius;
if (resolution === GRID_RESOLUTION.COARSE) {
radius = 64;
radius = 128;
} else if (resolution === GRID_RESOLUTION.FINE) {
radius = 32;
radius = 64;
} else if (resolution === GRID_RESOLUTION.MOST_FINE) {
radius = 16;
radius = 32;
} else {
throw new Error(`Refinement param not recognized: ${this._descriptor.refinement}`);
}

View file

@ -3,10 +3,14 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import _ from 'lodash';
export class DataRequest {
constructor(descriptor) {
this._descriptor = descriptor;
this._descriptor = {
...descriptor
};
}
getData() {
@ -18,7 +22,7 @@ export class DataRequest {
}
getMeta() {
return this._descriptor.dataMeta;
return _.get(this._descriptor, 'dataMeta', {});
}
hasDataOrRequestInProgress() {

View file

@ -15,7 +15,8 @@ export default function ({ getPageObjects, getService }) {
describe('layer geo grid aggregation source', () => {
const EXPECTED_NUMBER_FEATURES = 6;
const EXPECTED_NUMBER_FEATURES_ZOOMED_OUT = 4;
const EXPECTED_NUMBER_FEATURES_ZOOMED_IN = 6;
const DATA_CENTER_LON = -98;
const DATA_CENTER_LAT = 38;
@ -36,20 +37,28 @@ export default function ({ getPageObjects, getService }) {
beforeTimestamp = await getRequestTimestamp();
});
it('should not rerequest when zoom changes do not cause geohash precision to change', async () => {
await PageObjects.maps.setView(DATA_CENTER_LAT, DATA_CENTER_LON, 2);
it('should not rerequest when pan changes do not move map view area outside of buffer', async () => {
await PageObjects.maps.setView(DATA_CENTER_LAT + 10, DATA_CENTER_LON + 10, 1);
const afterTimestamp = await getRequestTimestamp();
expect(afterTimestamp).to.equal(beforeTimestamp);
});
it('should rerequest when zoom changes causes the geohash precision to change', async () => {
it('should not rerequest when zoom changes do not cause geotile_grid precision to change', async () => {
await PageObjects.maps.setView(DATA_CENTER_LAT, DATA_CENTER_LON, 1.2);
const beforeSameZoom = await getRequestTimestamp();
await PageObjects.maps.setView(DATA_CENTER_LAT, DATA_CENTER_LON, 1.8);
const afterTimestamp = await getRequestTimestamp();
expect(afterTimestamp).to.equal(beforeSameZoom);
});
it('should rerequest when zoom changes causes the geotile_grid precision to change', async () => {
await PageObjects.maps.setView(DATA_CENTER_LAT, DATA_CENTER_LON, 4);
const afterTimestamp = await getRequestTimestamp();
expect(afterTimestamp).not.to.equal(beforeTimestamp);
});
});
describe('geoprecision - data', async ()=> {
describe('geotile grid precision - data', async ()=> {
beforeEach(async () => {
await PageObjects.maps.setView(DATA_CENTER_LAT, DATA_CENTER_LON, 1);
@ -63,11 +72,11 @@ export default function ({ getPageObjects, getService }) {
it ('should request the data when the map covers the databounds', async () => {
const mapboxStyle = await PageObjects.maps.getMapboxStyle();
expect(mapboxStyle.sources[LAYER_ID].data.features.length).to.equal(EXPECTED_NUMBER_FEATURES);
expect(mapboxStyle.sources[LAYER_ID].data.features.length).to.equal(EXPECTED_NUMBER_FEATURES_ZOOMED_OUT);
});
it ('should request only partial data when the map only covers part of the databounds', async () => {
//todo this verifies the extent-filtering behavior (not really the correct application of geohash-precision), and should ideally be moved to its own section
//todo this verifies the extent-filtering behavior (not really the correct application of geotile_grid-precision), and should ideally be moved to its own section
await PageObjects.maps.setView(DATA_CENTER_LAT, DATA_CENTER_LON, 6);
const mapboxStyle = await PageObjects.maps.getMapboxStyle();
expect(mapboxStyle.sources[LAYER_ID].data.features.length).to.equal(2);
@ -77,13 +86,13 @@ export default function ({ getPageObjects, getService }) {
describe('heatmap', () => {
before(async () => {
await PageObjects.maps.loadSavedMap('geohashgrid heatmap example');
await PageObjects.maps.loadSavedMap('geo grid heatmap example');
});
const LAYER_ID = '3xlvm';
const HEATMAP_PROP_NAME = '__kbn_heatmap_weight__';
it('should re-fetch geohashgrid aggregation with refresh timer', async () => {
it('should re-fetch geotile_grid aggregation with refresh timer', async () => {
const beforeRefreshTimerTimestamp = await getRequestTimestamp();
expect(beforeRefreshTimerTimestamp.length).to.be(24);
await PageObjects.maps.triggerSingleRefresh(1000);
@ -93,7 +102,7 @@ export default function ({ getPageObjects, getService }) {
it('should decorate feature properties with scaled doc_count property', async () => {
const mapboxStyle = await PageObjects.maps.getMapboxStyle();
expect(mapboxStyle.sources[LAYER_ID].data.features.length).to.equal(EXPECTED_NUMBER_FEATURES);
expect(mapboxStyle.sources[LAYER_ID].data.features.length).to.equal(EXPECTED_NUMBER_FEATURES_ZOOMED_IN);
mapboxStyle.sources[LAYER_ID].data.features.forEach(({ properties }) => {
expect(properties.hasOwnProperty(HEATMAP_PROP_NAME)).to.be(true);
@ -115,7 +124,7 @@ export default function ({ getPageObjects, getService }) {
await queryBar.submitQuery();
});
it('should apply query to geohashgrid aggregation request', async () => {
it('should apply query to geotile_grid aggregation request', async () => {
await PageObjects.maps.openInspectorRequestsView();
const requestStats = await inspector.getTableData();
const hits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits (total)');
@ -129,7 +138,7 @@ export default function ({ getPageObjects, getService }) {
await inspector.close();
});
it('should contain geohashgrid aggregation elasticsearch request', async () => {
it('should contain geotile_grid aggregation elasticsearch request', async () => {
await PageObjects.maps.openInspectorRequestsView();
const requestStats = await inspector.getTableData();
const totalHits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits (total)');
@ -150,14 +159,14 @@ export default function ({ getPageObjects, getService }) {
describe('vector(grid)', () => {
before(async () => {
await PageObjects.maps.loadSavedMap('geohashgrid vector grid example');
await PageObjects.maps.loadSavedMap('geo grid vector grid example');
});
const LAYER_ID = 'g1xkv';
const MAX_OF_BYTES_PROP_NAME = 'max_of_bytes';
it('should re-fetch geohashgrid aggregation with refresh timer', async () => {
it('should re-fetch geotile_grid aggregation with refresh timer', async () => {
const beforeRefreshTimerTimestamp = await getRequestTimestamp();
expect(beforeRefreshTimerTimestamp.length).to.be(24);
await PageObjects.maps.triggerSingleRefresh(1000);
@ -167,7 +176,7 @@ export default function ({ getPageObjects, getService }) {
it('should decorate feature properties with metrics properterties', async () => {
const mapboxStyle = await PageObjects.maps.getMapboxStyle();
expect(mapboxStyle.sources[LAYER_ID].data.features.length).to.equal(EXPECTED_NUMBER_FEATURES);
expect(mapboxStyle.sources[LAYER_ID].data.features.length).to.equal(EXPECTED_NUMBER_FEATURES_ZOOMED_IN);
mapboxStyle.sources[LAYER_ID].data.features.forEach(({ properties }) => {
expect(properties.hasOwnProperty(MAX_OF_BYTES_PROP_NAME)).to.be(true);
@ -190,7 +199,7 @@ export default function ({ getPageObjects, getService }) {
await queryBar.submitQuery();
});
it('should apply query to geohashgrid aggregation request', async () => {
it('should apply query to geotile_grid aggregation request', async () => {
await PageObjects.maps.openInspectorRequestsView();
const requestStats = await inspector.getTableData();
const hits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits (total)');
@ -204,7 +213,7 @@ export default function ({ getPageObjects, getService }) {
await inspector.close();
});
it('should contain geohashgrid aggregation elasticsearch request', async () => {
it('should contain geotile_grid aggregation elasticsearch request', async () => {
await PageObjects.maps.openInspectorRequestsView();
const requestStats = await inspector.getTableData();
const totalHits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits (total)');

View file

@ -32,7 +32,7 @@ export default function ({ getPageObjects, getService }) {
return hits;
}
it('should re-fetch geohashgrid aggregation with refresh timer', async () => {
it('should re-fetch documents with refresh timer', async () => {
const beforeRefreshTimerTimestamp = await getRequestTimestamp();
expect(beforeRefreshTimerTimestamp.length).to.be(24);
await PageObjects.maps.triggerSingleRefresh(1000);

View file

@ -190,7 +190,7 @@
"source": {
"type" : "map",
"map" : {
"title" : "geohashgrid heatmap example",
"title" : "geo grid heatmap example",
"mapStateJSON" : "{\"zoom\":3.59,\"center\":{\"lon\":-98.05765,\"lat\":38.32288},\"timeFilters\":{\"from\":\"2015-09-20T00:00:00.000Z\",\"to\":\"2015-09-20T01:00:00.000Z\"},\"refreshConfig\":{\"isPaused\":true,\"interval\":1000}}",
"layerListJSON" : "[{\"id\":\"0hmz5\",\"sourceDescriptor\":{\"type\":\"EMS_TMS\",\"id\":\"road_map\"},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"TILE\",\"properties\":{\"alphaValue\":1}},\"type\":\"TILE\",\"minZoom\":0,\"maxZoom\":24},{\"id\":\"3xlvm\",\"label\":null,\"minZoom\":0,\"maxZoom\":24,\"sourceDescriptor\":{\"resolution\": \"COARSE\",\"type\":\"ES_GEO_GRID\",\"id\":\"427aa49d-a552-4e7d-a629-67c47db27128\",\"indexPatternId\":\"c698b940-e149-11e8-a35a-370a8516603a\",\"geoField\":\"geo.coordinates\",\"requestType\":\"heatmap\"},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"HEATMAP\",\"refinement\":\"coarse\",\"properties\":{\"alphaValue\":1},\"previousStyle\":null},\"type\":\"HEATMAP\"}]",
"uiStateJSON" : "{\"isDarkMode\":false}",
@ -220,7 +220,7 @@
"source": {
"type" : "map",
"map" : {
"title" : "geohashgrid vector grid example",
"title" : "geo grid vector grid example",
"description" : "",
"mapStateJSON" : "{\"zoom\":3.59,\"center\":{\"lon\":-98.05765,\"lat\":38.32288},\"timeFilters\":{\"from\":\"2015-09-20T00:00:00.000Z\",\"to\":\"2015-09-20T01:00:00.000Z\"},\"refreshConfig\":{\"isPaused\":true,\"interval\":1000}}",
"layerListJSON" : "[{\"id\":\"0hmz5\",\"sourceDescriptor\":{\"type\":\"EMS_TMS\",\"id\":\"road_map\"},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"TILE\",\"properties\":{\"alphaValue\":1}},\"type\":\"TILE\",\"minZoom\":0,\"maxZoom\":24},{\"id\":\"g1xkv\",\"label\":null,\"minZoom\":0,\"maxZoom\":24,\"sourceDescriptor\":{\"resolution\": \"COARSE\",\"type\":\"ES_GEO_GRID\",\"id\":\"9305f6ea-4518-4c06-95b9-33321aa38d6a\",\"indexPatternId\":\"c698b940-e149-11e8-a35a-370a8516603a\",\"geoField\":\"geo.coordinates\",\"requestType\":\"grid\",\"metrics\":[{\"type\":\"count\"},{\"type\":\"max\",\"field\":\"bytes\"}]},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"label\":\"max of bytes\",\"name\":\"max_of_bytes\",\"origin\":\"source\"},\"color\":\"Blues\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#cccccc\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"label\":\"Count\",\"name\":\"doc_count\",\"origin\":\"source\"},\"minSize\":4,\"maxSize\":32}},\"alphaValue\":1},\"temporary\":true,\"previousStyle\":null},\"type\":\"VECTOR\"}]",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 468 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Before After
Before After