From 25dd188cb5175713cb24035c5f6fcca7c0bd92e4 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 2 Mar 2021 16:48:02 -0500 Subject: [PATCH] [Maps] Update Map extent queries to use bounding box logic for both point and shape queries (#93156) --- .../elasticsearch_geo_utils.d.ts | 3 +- .../elasticsearch_geo_utils.js | 26 +-- .../elasticsearch_geo_utils.test.js | 202 +++++++----------- .../classes/sources/es_source/es_source.ts | 8 +- 4 files changed, 84 insertions(+), 155 deletions(-) diff --git a/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.d.ts b/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.d.ts index d7d76ab8acd372..2a3741146d454e 100644 --- a/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.d.ts +++ b/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.d.ts @@ -47,8 +47,7 @@ export interface ESPolygonFilter { export function createExtentFilter( mapExtent: MapExtent, - geoFieldName: string, - geoFieldType: ES_GEO_FIELD_TYPE + geoFieldName: string ): ESPolygonFilter | ESGeoBoundingBoxFilter; export function makeESBbox({ maxLat, maxLon, minLat, minLon }: MapExtent): ESBBox; diff --git a/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.js b/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.js index c6b1c712925f01..47de8850c0e969 100644 --- a/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.js +++ b/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.js @@ -280,8 +280,8 @@ export function makeESBbox({ maxLat, maxLon, minLat, minLon }) { return esBbox; } -function createGeoBoundBoxFilter({ maxLat, maxLon, minLat, minLon }, geoFieldName) { - const boundingBox = makeESBbox({ maxLat, maxLon, minLat, minLon }); +export function createExtentFilter(mapExtent, geoFieldName) { + const boundingBox = makeESBbox(mapExtent); return { geo_bounding_box: { [geoFieldName]: boundingBox, @@ -289,28 +289,6 @@ function createGeoBoundBoxFilter({ maxLat, maxLon, minLat, minLon }, geoFieldNam }; } -export function createExtentFilter(mapExtent, geoFieldName, geoFieldType) { - ensureGeoField(geoFieldType); - - // Extent filters are used to dynamically filter data for the current map view port. - // Continue to use geo_bounding_box queries for extent filters - // 1) geo_bounding_box queries are faster than polygon queries - // 2) geo_shape benefits of pre-indexed shapes and - // compatability across multi-indices with geo_point and geo_shape do not apply to this use case. - if (geoFieldType === ES_GEO_FIELD_TYPE.GEO_POINT) { - return createGeoBoundBoxFilter(mapExtent, geoFieldName); - } - - return { - geo_shape: { - [geoFieldName]: { - shape: formatEnvelopeAsPolygon(mapExtent), - relation: ES_SPATIAL_RELATIONS.INTERSECTS, - }, - }, - }; -} - export function createSpatialFilterWithGeometry({ preIndexedShape, geometry, diff --git a/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.test.js b/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.test.js index aed9ccbb96c3bc..9983bb9b845882 100644 --- a/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.test.js +++ b/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.test.js @@ -389,143 +389,99 @@ describe('geoShapeToGeometry', () => { }); describe('createExtentFilter', () => { - describe('geo_point field', () => { - it('should return elasticsearch geo_bounding_box filter for geo_point field', () => { - const mapExtent = { - maxLat: 39, - maxLon: -83, - minLat: 35, - minLon: -89, - }; - const filter = createExtentFilter(mapExtent, geoFieldName, 'geo_point'); - expect(filter).toEqual({ - geo_bounding_box: { - location: { - top_left: [-89, 39], - bottom_right: [-83, 35], - }, - }, - }); - }); - - it('should clamp longitudes to -180 to 180 and latitudes to -90 to 90', () => { - const mapExtent = { - maxLat: 120, - maxLon: 200, - minLat: -100, - minLon: -190, - }; - const filter = createExtentFilter(mapExtent, geoFieldName, 'geo_point'); - expect(filter).toEqual({ - geo_bounding_box: { - location: { - top_left: [-180, 89], - bottom_right: [180, -89], - }, + it('should return elasticsearch geo_bounding_box filter', () => { + const mapExtent = { + maxLat: 39, + maxLon: -83, + minLat: 35, + minLon: -89, + }; + const filter = createExtentFilter(mapExtent, geoFieldName); + expect(filter).toEqual({ + geo_bounding_box: { + location: { + top_left: [-89, 39], + bottom_right: [-83, 35], }, - }); + }, }); + }); - it('should make left longitude greater then right longitude when area crosses 180 meridian east to west', () => { - const mapExtent = { - maxLat: 39, - maxLon: 200, - minLat: 35, - minLon: 100, - }; - const filter = createExtentFilter(mapExtent, geoFieldName, 'geo_point'); - const leftLon = filter.geo_bounding_box.location.top_left[0]; - const rightLon = filter.geo_bounding_box.location.bottom_right[0]; - expect(leftLon).toBeGreaterThan(rightLon); - expect(filter).toEqual({ - geo_bounding_box: { - location: { - top_left: [100, 39], - bottom_right: [-160, 35], - }, + it('should clamp longitudes to -180 to 180 and latitudes to -90 to 90', () => { + const mapExtent = { + maxLat: 120, + maxLon: 200, + minLat: -100, + minLon: -190, + }; + const filter = createExtentFilter(mapExtent, geoFieldName); + expect(filter).toEqual({ + geo_bounding_box: { + location: { + top_left: [-180, 89], + bottom_right: [180, -89], }, - }); + }, }); + }); - it('should make left longitude greater then right longitude when area crosses 180 meridian west to east', () => { - const mapExtent = { - maxLat: 39, - maxLon: -100, - minLat: 35, - minLon: -200, - }; - const filter = createExtentFilter(mapExtent, geoFieldName, 'geo_point'); - const leftLon = filter.geo_bounding_box.location.top_left[0]; - const rightLon = filter.geo_bounding_box.location.bottom_right[0]; - expect(leftLon).toBeGreaterThan(rightLon); - expect(filter).toEqual({ - geo_bounding_box: { - location: { - top_left: [160, 39], - bottom_right: [-100, 35], - }, + it('should make left longitude greater then right longitude when area crosses 180 meridian east to west', () => { + const mapExtent = { + maxLat: 39, + maxLon: 200, + minLat: 35, + minLon: 100, + }; + const filter = createExtentFilter(mapExtent, geoFieldName); + const leftLon = filter.geo_bounding_box.location.top_left[0]; + const rightLon = filter.geo_bounding_box.location.bottom_right[0]; + expect(leftLon).toBeGreaterThan(rightLon); + expect(filter).toEqual({ + geo_bounding_box: { + location: { + top_left: [100, 39], + bottom_right: [-160, 35], }, - }); + }, }); }); - describe('geo_shape field', () => { - it('should return elasticsearch geo_shape filter', () => { - const mapExtent = { - maxLat: 39, - maxLon: -83, - minLat: 35, - minLon: -89, - }; - const filter = createExtentFilter(mapExtent, geoFieldName, 'geo_shape'); - expect(filter).toEqual({ - geo_shape: { - location: { - relation: 'INTERSECTS', - shape: { - coordinates: [ - [ - [-89, 39], - [-89, 35], - [-83, 35], - [-83, 39], - [-89, 39], - ], - ], - type: 'Polygon', - }, - }, + it('should make left longitude greater then right longitude when area crosses 180 meridian west to east', () => { + const mapExtent = { + maxLat: 39, + maxLon: -100, + minLat: 35, + minLon: -200, + }; + const filter = createExtentFilter(mapExtent, geoFieldName); + const leftLon = filter.geo_bounding_box.location.top_left[0]; + const rightLon = filter.geo_bounding_box.location.bottom_right[0]; + expect(leftLon).toBeGreaterThan(rightLon); + expect(filter).toEqual({ + geo_bounding_box: { + location: { + top_left: [160, 39], + bottom_right: [-100, 35], }, - }); + }, }); + }); - it('should clamp longitudes to -180 to 180 when lonitude wraps globe', () => { - const mapExtent = { - maxLat: 39, - maxLon: 209, - minLat: 35, - minLon: -191, - }; - const filter = createExtentFilter(mapExtent, geoFieldName, 'geo_shape'); - expect(filter).toEqual({ - geo_shape: { - location: { - relation: 'INTERSECTS', - shape: { - coordinates: [ - [ - [-180, 39], - [-180, 35], - [180, 35], - [180, 39], - [-180, 39], - ], - ], - type: 'Polygon', - }, - }, + it('should clamp longitudes to -180 to 180 when longitude wraps globe', () => { + const mapExtent = { + maxLat: 39, + maxLon: 209, + minLat: 35, + minLon: -191, + }; + const filter = createExtentFilter(mapExtent, geoFieldName); + expect(filter).toEqual({ + geo_bounding_box: { + location: { + top_left: [-180, 39], + bottom_right: [180, 35], }, - }); + }, }); }); }); diff --git a/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts b/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts index f6f0a234bcd67f..6b99f1f8860c03 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts @@ -34,7 +34,7 @@ import { import { IVectorStyle } from '../../styles/vector/vector_style'; import { IDynamicStyleProperty } from '../../styles/vector/properties/dynamic_style_property'; import { IField } from '../../fields/field'; -import { ES_GEO_FIELD_TYPE, FieldFormatter } from '../../../../common/constants'; +import { FieldFormatter } from '../../../../common/constants'; import { Adapters, RequestResponder, @@ -236,11 +236,7 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource typeof searchFilters.geogridPrecision === 'number' ? expandToTileBoundaries(searchFilters.buffer, searchFilters.geogridPrecision) : searchFilters.buffer; - const extentFilter = createExtentFilter( - buffer, - geoField.name, - geoField.type as ES_GEO_FIELD_TYPE - ); + const extentFilter = createExtentFilter(buffer, geoField.name); // @ts-expect-error allFilters.push(extentFilter);