Skip to content

Commit

Permalink
[Maps] update geospatial filters to use geo_shape query for geo_point…
Browse files Browse the repository at this point in the history
… fields (#62966) (#63394)

Co-authored-by: Elastic Machine <[email protected]>

Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
nreese and elasticmachine authored Apr 14, 2020
1 parent 5b9708d commit d0bcd06
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import DrawRectangle from 'mapbox-gl-draw-rectangle-mode';
import { DrawCircle } from './draw_circle';
import {
createDistanceFilterWithMeta,
createSpatialFilterWithBoundingBox,
createSpatialFilterWithGeometry,
getBoundingBoxGeometry,
roundCoordinates,
Expand Down Expand Up @@ -84,23 +83,17 @@ export class DrawControl extends React.Component {
roundCoordinates(geometry.coordinates);

try {
const options = {
const filter = createSpatialFilterWithGeometry({
geometry:
this.props.drawState.drawType === DRAW_TYPE.BOUNDS
? getBoundingBoxGeometry(geometry)
: geometry,
indexPatternId: this.props.drawState.indexPatternId,
geoFieldName: this.props.drawState.geoFieldName,
geoFieldType: this.props.drawState.geoFieldType,
geometryLabel: this.props.drawState.geometryLabel,
relation: this.props.drawState.relation,
};
const filter =
this.props.drawState.drawType === DRAW_TYPE.BOUNDS
? createSpatialFilterWithBoundingBox({
...options,
geometry: getBoundingBoxGeometry(geometry),
})
: createSpatialFilterWithGeometry({
...options,
geometry,
});
});
this.props.addFilters([filter]);
} catch (error) {
// TODO notify user why filter was not created
Expand Down
99 changes: 28 additions & 71 deletions x-pack/plugins/maps/public/elasticsearch_geo_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,28 +231,16 @@ function createGeoBoundBoxFilter(geometry, geoFieldName, filterProps = {}) {
};
}

function createGeoPolygonFilter(polygonCoordinates, geoFieldName, filterProps = {}) {
return {
geo_polygon: {
ignore_unmapped: true,
[geoFieldName]: {
points: polygonCoordinates[POLYGON_COORDINATES_EXTERIOR_INDEX].map(coordinatePair => {
return {
lon: coordinatePair[LON_INDEX],
lat: coordinatePair[LAT_INDEX],
};
}),
},
},
...filterProps,
};
}

export function createExtentFilter(mapExtent, geoFieldName, geoFieldType) {
ensureGeoField(geoFieldType);

const safePolygon = convertMapExtentToPolygon(mapExtent);

// 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(safePolygon, geoFieldName);
}
Expand All @@ -267,32 +255,24 @@ export function createExtentFilter(mapExtent, geoFieldName, geoFieldType) {
};
}

export function createSpatialFilterWithBoundingBox(options) {
return createGeometryFilterWithMeta({ ...options, isBoundingBox: true });
}

export function createSpatialFilterWithGeometry(options) {
return createGeometryFilterWithMeta(options);
}

function createGeometryFilterWithMeta({
export function createSpatialFilterWithGeometry({
preIndexedShape,
geometry,
geometryLabel,
indexPatternId,
geoFieldName,
geoFieldType,
relation = ES_SPATIAL_RELATIONS.INTERSECTS,
isBoundingBox = false,
}) {
ensureGeoField(geoFieldType);

const relationLabel =
geoFieldType === ES_GEO_FIELD_TYPE.GEO_POINT
? i18n.translate('xpack.maps.es_geo_utils.shapeFilter.geoPointRelationLabel', {
defaultMessage: 'in',
})
: getEsSpatialRelationLabel(relation);
const isGeoPoint = geoFieldType === ES_GEO_FIELD_TYPE.GEO_POINT;

const relationLabel = isGeoPoint
? i18n.translate('xpack.maps.es_geo_utils.shapeFilter.geoPointRelationLabel', {
defaultMessage: 'in',
})
: getEsSpatialRelationLabel(relation);
const meta = {
type: SPATIAL_FILTER_TYPE,
negate: false,
Expand All @@ -301,47 +281,24 @@ function createGeometryFilterWithMeta({
alias: `${geoFieldName} ${relationLabel} ${geometryLabel}`,
};

if (geoFieldType === ES_GEO_FIELD_TYPE.GEO_SHAPE) {
const shapeQuery = {
relation,
};

if (preIndexedShape) {
shapeQuery.indexed_shape = preIndexedShape;
} else {
shapeQuery.shape = geometry;
}

return {
meta,
geo_shape: {
ignore_unmapped: true,
[geoFieldName]: shapeQuery,
},
};
}

// geo_points supports limited geometry types
ensureGeometryType(geometry.type, [GEO_JSON_TYPE.POLYGON, GEO_JSON_TYPE.MULTI_POLYGON]);

if (geometry.type === GEO_JSON_TYPE.MULTI_POLYGON) {
return {
meta,
query: {
bool: {
should: geometry.coordinates.map(polygonCoordinates => {
return createGeoPolygonFilter(polygonCoordinates, geoFieldName);
}),
},
},
};
}
const shapeQuery = {
// geo_shape query with geo_point field only supports intersects relation
relation: isGeoPoint ? ES_SPATIAL_RELATIONS.INTERSECTS : relation,
};

if (isBoundingBox) {
return createGeoBoundBoxFilter(geometry, geoFieldName, { meta });
if (preIndexedShape) {
shapeQuery.indexed_shape = preIndexedShape;
} else {
shapeQuery.shape = geometry;
}

return createGeoPolygonFilter(geometry.coordinates, geoFieldName, { meta });
return {
meta,
geo_shape: {
ignore_unmapped: true,
[geoFieldName]: shapeQuery,
},
};
}

export function createDistanceFilterWithMeta({
Expand Down

0 comments on commit d0bcd06

Please sign in to comment.