diff --git a/src/ui/public/agg_types/buckets/geo_tile.js b/src/ui/public/agg_types/buckets/geo_tile.js new file mode 100644 index 0000000000000..ca85185f568f4 --- /dev/null +++ b/src/ui/public/agg_types/buckets/geo_tile.js @@ -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; + } +}); diff --git a/src/ui/public/agg_types/index.js b/src/ui/public/agg_types/index.js index 8989672723927..93ca63ccde786 100644 --- a/src/ui/public/agg_types/index.js +++ b/src/ui/public/agg_types/index.js @@ -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, ] }; diff --git a/x-pack/plugins/maps/public/elasticsearch_geo_utils.js b/x-pack/plugins/maps/public/elasticsearch_geo_utils.js index 5ebb181465fdb..68de2fa64ef38 100644 --- a/x-pack/plugins/maps/public/elasticsearch_geo_utils.js +++ b/x-pack/plugins/maps/public/elasticsearch_geo_utils.js @@ -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 []; diff --git a/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/convert_to_geojson.js b/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/convert_to_geojson.js index c1c47db188221..4b2bfca02acd5 100644 --- a/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/convert_to_geojson.js +++ b/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/convert_to_geojson.js @@ -4,113 +4,98 @@ * 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) { - - let features; - const min = Infinity; - const max = -Infinity; - let geoAgg; - - 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 EMPTY_FEATURE_COLLECTION = { + type: 'FeatureCollection', + features: [] +}; - 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]], - ]; +export function convertToGeoJson({ table, renderAs }) { - 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]); - } + if (!table || !table.rows) { + return EMPTY_FEATURE_COLLECTION; + } - 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); + const geoGridColumn = table.columns.find(column => column.aggConfig.type.dslName === 'geotile_grid'); + if (!geoGridColumn) { + return EMPTY_FEATURE_COLLECTION; + } - return { - type: 'Feature', - geometry: { - type: 'Point', - coordinates: pointCoordinates - }, - properties: { - geohash: geohash, - geohash_meta: { - center: centerLatLng, - rectangle: rectangle - }, - ...metrics - } - }; + 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; + } - }).filter(row => row); + 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: { + type: 'FeatureCollection', + features: features } + }; +} - } else { - 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], + ] + ] + }; } - const featureCollection = { - type: 'FeatureCollection', - features: features - }; + // 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 { - featureCollection: featureCollection, - meta: { - min: min, - max: max, - geohashGridDimensionsAtEquator: geoAgg && gridDimensions(geoAgg.params.precision) - } + type: 'Point', + coordinates: pointCoordinates }; } diff --git a/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/es_geo_grid_source.js b/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/es_geo_grid_source.js index 9d9a4754b35d4..766ba3e26d915 100644 --- a/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/es_geo_grid_source.js +++ b/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/es_geo_grid_source.js @@ -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, } - } + }, ]; } diff --git a/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/geo_tile_utils.js b/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/geo_tile_utils.js new file mode 100644 index 0000000000000..327d8ccf8d04e --- /dev/null +++ b/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/geo_tile_utils.js @@ -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), + }; +} diff --git a/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/geo_tile_utils.test.js b/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/geo_tile_utils.test.js new file mode 100644 index 0000000000000..2480eb2d29807 --- /dev/null +++ b/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/geo_tile_utils.test.js @@ -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 + }); +}); diff --git a/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/update_source_editor.js b/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/update_source_editor.js index e7a4bda2a126d..1293fc3f5db2d 100644 --- a/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/update_source_editor.js +++ b/x-pack/plugins/maps/public/shared/layers/sources/es_geo_grid_source/update_source_editor.js @@ -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); diff --git a/x-pack/plugins/maps/public/shared/layers/sources/kibana_tilemap_source/create_source_editor.js b/x-pack/plugins/maps/public/shared/layers/sources/kibana_tilemap_source/create_source_editor.js index b20ccc1314f24..0db7b438908d7 100644 --- a/x-pack/plugins/maps/public/shared/layers/sources/kibana_tilemap_source/create_source_editor.js +++ b/x-pack/plugins/maps/public/shared/layers/sources/kibana_tilemap_source/create_source_editor.js @@ -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; diff --git a/x-pack/plugins/maps/public/shared/layers/styles/heatmap_style.js b/x-pack/plugins/maps/public/shared/layers/styles/heatmap_style.js index fffeb66b9b04c..2fa18b0bda14a 100644 --- a/x-pack/plugins/maps/public/shared/layers/styles/heatmap_style.js +++ b/x-pack/plugins/maps/public/shared/layers/styles/heatmap_style.js @@ -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}`); } diff --git a/x-pack/plugins/maps/public/shared/layers/util/data_request.js b/x-pack/plugins/maps/public/shared/layers/util/data_request.js index 5abc2f7d088a7..91341997a60d8 100644 --- a/x-pack/plugins/maps/public/shared/layers/util/data_request.js +++ b/x-pack/plugins/maps/public/shared/layers/util/data_request.js @@ -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() { diff --git a/x-pack/test/functional/apps/maps/es_geo_grid_source.js b/x-pack/test/functional/apps/maps/es_geo_grid_source.js index 66d60f181f420..4d98e0b9f2cdb 100644 --- a/x-pack/test/functional/apps/maps/es_geo_grid_source.js +++ b/x-pack/test/functional/apps/maps/es_geo_grid_source.js @@ -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)'); diff --git a/x-pack/test/functional/apps/maps/es_search_source.js b/x-pack/test/functional/apps/maps/es_search_source.js index 76dbd803337c2..0528febceeb0a 100644 --- a/x-pack/test/functional/apps/maps/es_search_source.js +++ b/x-pack/test/functional/apps/maps/es_search_source.js @@ -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); diff --git a/x-pack/test/functional/es_archives/maps/kibana/data.json b/x-pack/test/functional/es_archives/maps/kibana/data.json index e616a2af5cf31..cb496c951f2ad 100644 --- a/x-pack/test/functional/es_archives/maps/kibana/data.json +++ b/x-pack/test/functional/es_archives/maps/kibana/data.json @@ -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\"}]", diff --git a/x-pack/test/functional/screenshots/baseline/ecommerce_map.png b/x-pack/test/functional/screenshots/baseline/ecommerce_map.png index f65bf2d38823c..1450e48012a0b 100644 Binary files a/x-pack/test/functional/screenshots/baseline/ecommerce_map.png and b/x-pack/test/functional/screenshots/baseline/ecommerce_map.png differ diff --git a/x-pack/test/functional/screenshots/baseline/flights_map.png b/x-pack/test/functional/screenshots/baseline/flights_map.png index 513f0a95f058b..2a896652e4204 100644 Binary files a/x-pack/test/functional/screenshots/baseline/flights_map.png and b/x-pack/test/functional/screenshots/baseline/flights_map.png differ diff --git a/x-pack/test/functional/screenshots/baseline/web_logs_map.png b/x-pack/test/functional/screenshots/baseline/web_logs_map.png index 2f8fbab322a65..0f2bfed5e0dde 100644 Binary files a/x-pack/test/functional/screenshots/baseline/web_logs_map.png and b/x-pack/test/functional/screenshots/baseline/web_logs_map.png differ