mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
* Clamp the centroid to stay within the box boundaries If a document has two or more geo fields, then the centroid calculation will place the centroid in between the two geo fields. This can cause the centroid to be in the middle of nowhere so clamp it to keep it closer to where it should be. * Add geocentroid and clamping tests
This commit is contained in:
parent
3095b3bffb
commit
a93ee59b5a
2 changed files with 106 additions and 16 deletions
|
@ -15,6 +15,8 @@ describe('GeoJson Agg Response Converter', function () {
|
|||
let esResponse;
|
||||
let expectedAggs;
|
||||
|
||||
let createVis;
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (Private) {
|
||||
const Vis = Private(VisProvider);
|
||||
|
@ -24,22 +26,29 @@ describe('GeoJson Agg Response Converter', function () {
|
|||
tabify = Private(AggResponseTabifyProvider);
|
||||
convert = Private(AggResponseGeoJsonProvider);
|
||||
|
||||
vis = new Vis(indexPattern, {
|
||||
type: 'tile_map',
|
||||
aggs: [
|
||||
{ schema: 'metric', type: 'avg', params: { field: 'bytes' } },
|
||||
{ schema: 'segment', type: 'geohash_grid', params: { field: 'geo.coordinates', precision: 3, useGeocentroid: false } }
|
||||
],
|
||||
params: {
|
||||
isDesaturated: true,
|
||||
mapType: 'Scaled%20Circle%20Markers'
|
||||
}
|
||||
});
|
||||
createVis = function (useGeocentroid) {
|
||||
vis = new Vis(indexPattern, {
|
||||
type: 'tile_map',
|
||||
aggs: [
|
||||
{ schema: 'metric', type: 'avg', params: { field: 'bytes' } },
|
||||
{ schema: 'segment', type: 'geohash_grid', params: { field: 'geo.coordinates', precision: 3, useGeocentroid: useGeocentroid } }
|
||||
],
|
||||
params: {
|
||||
isDesaturated: true,
|
||||
mapType: 'Scaled%20Circle%20Markers'
|
||||
}
|
||||
});
|
||||
|
||||
expectedAggs = {
|
||||
metric: vis.aggs[0],
|
||||
geo: vis.aggs[1]
|
||||
expectedAggs = {
|
||||
metric: vis.aggs[0],
|
||||
geo: vis.aggs[1]
|
||||
};
|
||||
if (useGeocentroid) {
|
||||
expectedAggs.centroid = vis.aggs[2];
|
||||
}
|
||||
};
|
||||
|
||||
createVis(false);
|
||||
}));
|
||||
|
||||
[ { asAggConfigResults: true }, { asAggConfigResults: false } ].forEach(function (tableOpts) {
|
||||
|
@ -174,6 +183,80 @@ describe('GeoJson Agg Response Converter', function () {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('geocentroid', function () {
|
||||
const createEsResponse = function (position = { lat: 37, lon: -122 }) {
|
||||
esResponse = {
|
||||
took: 1,
|
||||
timed_out: false,
|
||||
_shards: {
|
||||
total: 4,
|
||||
successful: 4,
|
||||
failed: 0
|
||||
},
|
||||
hits: {
|
||||
total: 61005,
|
||||
max_score: 0.0,
|
||||
hits: []
|
||||
},
|
||||
aggregations: {
|
||||
2: {
|
||||
buckets: [{
|
||||
key: '9q',
|
||||
doc_count: 10307,
|
||||
1: {
|
||||
value: 10307
|
||||
},
|
||||
3: {
|
||||
location: position
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
createEsResponse();
|
||||
createVis(true);
|
||||
});
|
||||
|
||||
it('should use geocentroid', function () {
|
||||
const chart = makeSingleChart();
|
||||
expect(chart.geoJson.features[0].geometry.coordinates).to.eql([ -122, 37 ]);
|
||||
});
|
||||
|
||||
// 9q has latitude boundaries of 33.75 to 39.375
|
||||
// 9q has longituted boundaries of -123.75 to -112.5
|
||||
[
|
||||
{
|
||||
lat: 30,
|
||||
lon: -122,
|
||||
expected: [ -122, 33.75 ]
|
||||
},
|
||||
{
|
||||
lat: 45,
|
||||
lon: -122,
|
||||
expected: [ -122, 39.375 ]
|
||||
},
|
||||
{
|
||||
lat: 37,
|
||||
lon: -130,
|
||||
expected: [ -123.75, 37 ]
|
||||
},
|
||||
{
|
||||
lat: 37,
|
||||
lon: -110,
|
||||
expected: [ -112.5, 37 ]
|
||||
}
|
||||
].forEach(function (position) {
|
||||
it('should clamp geocentroid ' + JSON.stringify(position), function () {
|
||||
createEsResponse(position);
|
||||
const chart = makeSingleChart();
|
||||
expect(chart.geoJson.features[0].geometry.coordinates).to.eql(position.expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,6 +10,12 @@ function unwrap(val) {
|
|||
return getAcr(val) ? val.value : val;
|
||||
}
|
||||
|
||||
function clampGrid(val, min, max) {
|
||||
if (val > max) val = max;
|
||||
else if (val < min) val = min;
|
||||
return val;
|
||||
}
|
||||
|
||||
export function convertRowsToFeatures(table, geoI, metricI, centroidI) {
|
||||
|
||||
return _.transform(table.rows, function (features, row) {
|
||||
|
@ -28,9 +34,10 @@ export function convertRowsToFeatures(table, geoI, metricI, centroidI) {
|
|||
let point = centerLatLng;
|
||||
const centroid = unwrap(row[centroidI]);
|
||||
if (centroid) {
|
||||
// see https://github.com/elastic/elasticsearch/issues/24694 for why clampGrid is used
|
||||
point = [
|
||||
centroid.lat,
|
||||
centroid.lon
|
||||
clampGrid(centroid.lat, location.latitude[0], location.latitude[1]),
|
||||
clampGrid(centroid.lon, location.longitude[0], location.longitude[1])
|
||||
];
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue