[Maps] geo_shape fit to bounds (#64303)
* [Maps] geo_shape fit to bounds * handle results that cross dateline Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
4d3e60be39
commit
1252b832f4
4 changed files with 72 additions and 107 deletions
|
@ -18,7 +18,6 @@ import { i18n } from '@kbn/i18n';
|
||||||
import uuid from 'uuid/v4';
|
import uuid from 'uuid/v4';
|
||||||
|
|
||||||
import { copyPersistentState } from '../../../reducers/util';
|
import { copyPersistentState } from '../../../reducers/util';
|
||||||
import { ES_GEO_FIELD_TYPE } from '../../../../common/constants';
|
|
||||||
import { DataRequestAbortError } from '../../util/data_request';
|
import { DataRequestAbortError } from '../../util/data_request';
|
||||||
import { expandToTileBoundaries } from '../es_geo_grid_source/geo_tile_utils';
|
import { expandToTileBoundaries } from '../es_geo_grid_source/geo_tile_utils';
|
||||||
|
|
||||||
|
@ -176,9 +175,11 @@ export class AbstractESSource extends AbstractVectorSource {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const minLon = esBounds.top_left.lon;
|
||||||
|
const maxLon = esBounds.bottom_right.lon;
|
||||||
return {
|
return {
|
||||||
minLon: esBounds.top_left.lon,
|
minLon: minLon > maxLon ? minLon - 360 : minLon,
|
||||||
maxLon: esBounds.bottom_right.lon,
|
maxLon,
|
||||||
minLat: esBounds.bottom_right.lat,
|
minLat: esBounds.bottom_right.lat,
|
||||||
maxLat: esBounds.top_left.lat,
|
maxLat: esBounds.top_left.lat,
|
||||||
};
|
};
|
||||||
|
@ -223,9 +224,7 @@ export class AbstractESSource extends AbstractVectorSource {
|
||||||
async supportsFitToBounds() {
|
async supportsFitToBounds() {
|
||||||
try {
|
try {
|
||||||
const geoField = await this._getGeoField();
|
const geoField = await this._getGeoField();
|
||||||
// geo_bounds aggregation only supports geo_point
|
return geoField.aggregatable;
|
||||||
// there is currently no backend support for getting bounding box of geo_shape field
|
|
||||||
return geoField.type !== ES_GEO_FIELD_TYPE.GEO_SHAPE;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,101 +8,74 @@ import { canSkipSourceUpdate, updateDueToExtent } from './can_skip_fetch';
|
||||||
import { DataRequest } from './data_request';
|
import { DataRequest } from './data_request';
|
||||||
|
|
||||||
describe('updateDueToExtent', () => {
|
describe('updateDueToExtent', () => {
|
||||||
it('should be false when the source is not extent aware', async () => {
|
it('should be false when buffers are the same', async () => {
|
||||||
const sourceMock = {
|
const oldBuffer = {
|
||||||
isFilterByMapBounds: () => {
|
maxLat: 12.5,
|
||||||
return false;
|
maxLon: 102.5,
|
||||||
},
|
minLat: 2.5,
|
||||||
|
minLon: 92.5,
|
||||||
};
|
};
|
||||||
expect(updateDueToExtent(sourceMock)).toBe(false);
|
const newBuffer = {
|
||||||
|
maxLat: 12.5,
|
||||||
|
maxLon: 102.5,
|
||||||
|
minLat: 2.5,
|
||||||
|
minLon: 92.5,
|
||||||
|
};
|
||||||
|
expect(updateDueToExtent({ buffer: oldBuffer }, { buffer: newBuffer })).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('source is extent aware', () => {
|
it('should be false when the new buffer is contained in the old buffer', async () => {
|
||||||
const sourceMock = {
|
const oldBuffer = {
|
||||||
isFilterByMapBounds: () => {
|
maxLat: 12.5,
|
||||||
return true;
|
maxLon: 102.5,
|
||||||
},
|
minLat: 2.5,
|
||||||
|
minLon: 92.5,
|
||||||
};
|
};
|
||||||
|
const newBuffer = {
|
||||||
|
maxLat: 10,
|
||||||
|
maxLon: 100,
|
||||||
|
minLat: 5,
|
||||||
|
minLon: 95,
|
||||||
|
};
|
||||||
|
expect(updateDueToExtent({ buffer: oldBuffer }, { buffer: newBuffer })).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
it('should be false when buffers are the same', async () => {
|
it('should be true when the new buffer is contained in the old buffer and the past results were truncated', async () => {
|
||||||
const oldBuffer = {
|
const oldBuffer = {
|
||||||
maxLat: 12.5,
|
maxLat: 12.5,
|
||||||
maxLon: 102.5,
|
maxLon: 102.5,
|
||||||
minLat: 2.5,
|
minLat: 2.5,
|
||||||
minLon: 92.5,
|
minLon: 92.5,
|
||||||
};
|
};
|
||||||
const newBuffer = {
|
const newBuffer = {
|
||||||
maxLat: 12.5,
|
maxLat: 10,
|
||||||
maxLon: 102.5,
|
maxLon: 100,
|
||||||
minLat: 2.5,
|
minLat: 5,
|
||||||
minLon: 92.5,
|
minLon: 95,
|
||||||
};
|
};
|
||||||
expect(updateDueToExtent(sourceMock, { buffer: oldBuffer }, { buffer: newBuffer })).toBe(
|
expect(
|
||||||
false
|
updateDueToExtent({ buffer: oldBuffer, areResultsTrimmed: true }, { buffer: newBuffer })
|
||||||
);
|
).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be false when the new buffer is contained in the old buffer', async () => {
|
it('should be true when meta has no old buffer', async () => {
|
||||||
const oldBuffer = {
|
expect(updateDueToExtent()).toBe(true);
|
||||||
maxLat: 12.5,
|
});
|
||||||
maxLon: 102.5,
|
|
||||||
minLat: 2.5,
|
|
||||||
minLon: 92.5,
|
|
||||||
};
|
|
||||||
const newBuffer = {
|
|
||||||
maxLat: 10,
|
|
||||||
maxLon: 100,
|
|
||||||
minLat: 5,
|
|
||||||
minLon: 95,
|
|
||||||
};
|
|
||||||
expect(updateDueToExtent(sourceMock, { buffer: oldBuffer }, { buffer: newBuffer })).toBe(
|
|
||||||
false
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be true when the new buffer is contained in the old buffer and the past results were truncated', async () => {
|
it('should be true when the new buffer is not contained in the old buffer', async () => {
|
||||||
const oldBuffer = {
|
const oldBuffer = {
|
||||||
maxLat: 12.5,
|
maxLat: 12.5,
|
||||||
maxLon: 102.5,
|
maxLon: 102.5,
|
||||||
minLat: 2.5,
|
minLat: 2.5,
|
||||||
minLon: 92.5,
|
minLon: 92.5,
|
||||||
};
|
};
|
||||||
const newBuffer = {
|
const newBuffer = {
|
||||||
maxLat: 10,
|
maxLat: 7.5,
|
||||||
maxLon: 100,
|
maxLon: 92.5,
|
||||||
minLat: 5,
|
minLat: -2.5,
|
||||||
minLon: 95,
|
minLon: 82.5,
|
||||||
};
|
};
|
||||||
expect(
|
expect(updateDueToExtent({ buffer: oldBuffer }, { buffer: newBuffer })).toBe(true);
|
||||||
updateDueToExtent(
|
|
||||||
sourceMock,
|
|
||||||
{ buffer: oldBuffer, areResultsTrimmed: true },
|
|
||||||
{ buffer: newBuffer }
|
|
||||||
)
|
|
||||||
).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be true when meta has no old buffer', async () => {
|
|
||||||
expect(updateDueToExtent(sourceMock)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be true when the new buffer is not contained in the old buffer', async () => {
|
|
||||||
const oldBuffer = {
|
|
||||||
maxLat: 12.5,
|
|
||||||
maxLon: 102.5,
|
|
||||||
minLat: 2.5,
|
|
||||||
minLon: 92.5,
|
|
||||||
};
|
|
||||||
const newBuffer = {
|
|
||||||
maxLat: 7.5,
|
|
||||||
maxLon: 92.5,
|
|
||||||
minLat: -2.5,
|
|
||||||
minLon: 82.5,
|
|
||||||
};
|
|
||||||
expect(updateDueToExtent(sourceMock, { buffer: oldBuffer }, { buffer: newBuffer })).toBe(
|
|
||||||
true
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -15,16 +15,7 @@ import { DataRequest } from './data_request';
|
||||||
const SOURCE_UPDATE_REQUIRED = true;
|
const SOURCE_UPDATE_REQUIRED = true;
|
||||||
const NO_SOURCE_UPDATE_REQUIRED = false;
|
const NO_SOURCE_UPDATE_REQUIRED = false;
|
||||||
|
|
||||||
export function updateDueToExtent(
|
export function updateDueToExtent(prevMeta: DataMeta = {}, nextMeta: DataMeta = {}) {
|
||||||
source: ISource,
|
|
||||||
prevMeta: DataMeta = {},
|
|
||||||
nextMeta: DataMeta = {}
|
|
||||||
) {
|
|
||||||
const extentAware = source.isFilterByMapBounds();
|
|
||||||
if (!extentAware) {
|
|
||||||
return NO_SOURCE_UPDATE_REQUIRED;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { buffer: previousBuffer } = prevMeta;
|
const { buffer: previousBuffer } = prevMeta;
|
||||||
const { buffer: newBuffer } = nextMeta;
|
const { buffer: newBuffer } = nextMeta;
|
||||||
|
|
||||||
|
@ -134,7 +125,10 @@ export async function canSkipSourceUpdate({
|
||||||
updateDueToPrecisionChange = !_.isEqual(prevMeta.geogridPrecision, nextMeta.geogridPrecision);
|
updateDueToPrecisionChange = !_.isEqual(prevMeta.geogridPrecision, nextMeta.geogridPrecision);
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateDueToExtentChange = updateDueToExtent(source, prevMeta, nextMeta);
|
let updateDueToExtentChange = false;
|
||||||
|
if (extentAware) {
|
||||||
|
updateDueToExtentChange = updateDueToExtent(prevMeta, nextMeta);
|
||||||
|
}
|
||||||
|
|
||||||
const updateDueToSourceMetaChange = !_.isEqual(prevMeta.sourceMeta, nextMeta.sourceMeta);
|
const updateDueToSourceMetaChange = !_.isEqual(prevMeta.sourceMeta, nextMeta.sourceMeta);
|
||||||
|
|
||||||
|
|
|
@ -175,8 +175,7 @@ export class VectorLayer extends AbstractLayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBounds(dataFilters) {
|
async getBounds(dataFilters) {
|
||||||
const isStaticLayer =
|
const isStaticLayer = !this.getSource().isBoundsAware();
|
||||||
!this.getSource().isBoundsAware() || !this.getSource().isFilterByMapBounds();
|
|
||||||
if (isStaticLayer) {
|
if (isStaticLayer) {
|
||||||
return this._getBoundsBasedOnData();
|
return this._getBoundsBasedOnData();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue