Browse Source

add focus:scale to /search requests with just viewport.*, calculated from bounding box diagonal, minimum of 1

pull/304/head
Stephen Hess 9 years ago
parent
commit
dcadc7832e
  1. 23
      query/search.js
  2. 2
      test/unit/fixture/search_linguistic_viewport.js
  3. 105
      test/unit/fixture/search_linguistic_viewport_min_diagonal.js
  4. 18
      test/unit/query/search.js

23
query/search.js

@ -1,7 +1,8 @@
var peliasQuery = require('pelias-query'),
defaults = require('./defaults'),
textParser = require('./text_parser'),
check = require('check-types');
check = require('check-types'),
geolib = require('geolib');
//------------------------------
// general-purpose search query
@ -74,10 +75,10 @@ function generateQuery( clean ){
check.number(clean['focus.viewport.min_lon']) &&
check.number(clean['focus.viewport.max_lon']) ) {
// calculate the centroid from the viewport box
// simply set focus:point:lat/lon, until we improve this with a radius
vs.set({
'focus:point:lat': clean['focus.viewport.min_lat'] + ( clean['focus.viewport.max_lat'] - clean['focus.viewport.min_lat'] ) / 2,
'focus:point:lon': clean['focus.viewport.min_lon'] + ( clean['focus.viewport.max_lon'] - clean['focus.viewport.min_lon'] ) / 2
'focus:point:lon': clean['focus.viewport.min_lon'] + ( clean['focus.viewport.max_lon'] - clean['focus.viewport.min_lon'] ) / 2,
'focus:scale': calculateDiagonalDistance(clean) + 'km'
});
}
@ -125,4 +126,20 @@ function generateQuery( clean ){
return query.render( vs );
}
// return diagonal distance in km, with min=1
function calculateDiagonalDistance(clean) {
var diagonalDistance = geolib.getDistance(
{ latitude: clean['focus.viewport.min_lat'], longitude: clean['focus.viewport.min_lon'] },
{ latitude: clean['focus.viewport.max_lat'], longitude: clean['focus.viewport.max_lon'] },
1000
) / 1000;
if (diagonalDistance === 0) {
return 1;
}
return diagonalDistance;
}
module.exports = generateQuery;

2
test/unit/fixture/search_linguistic_viewport.js

@ -44,7 +44,7 @@ module.exports = {
'lon': -82.50622
},
'offset': '1km',
'scale': '50km',
'scale': '994km',
'decay': 0.5
}
}

105
test/unit/fixture/search_linguistic_viewport_min_diagonal.js

@ -0,0 +1,105 @@
module.exports = {
'query': {
'filtered': {
'query': {
'bool': {
'must': [{
'match': {
'name.default': {
'query': 'test',
'boost': 1,
'analyzer': 'peliasOneEdgeGram'
}
}
}],
'should': [{
'match': {
'phrase.default': {
'query': 'test',
'analyzer': 'peliasPhrase',
'type': 'phrase',
'boost': 1,
'slop': 2
}
}
}, {
'function_score': {
'query': {
'match': {
'phrase.default': {
'analyzer': 'peliasPhrase',
'type': 'phrase',
'boost': 1,
'slop': 2,
'query': 'test'
}
}
},
'functions': [{
'linear': {
'center_point': {
'origin': {
'lat': 28.49136,
'lon': -87.50623
},
'offset': '1km',
'scale': '1km',
'decay': 0.5
}
}
}],
'score_mode': 'avg',
'boost_mode': 'replace'
}
},
{
'function_score': {
'query': {
'filtered': {
'filter': {
'exists': {
'field': 'popularity'
}
}
}
},
'max_boost': 2,
'score_mode': 'first',
'boost_mode': 'replace',
'filter': {
'or': [
{
'type': {
'value': 'admin0'
}
},
{
'type': {
'value': 'admin1'
}
},
{
'type': {
'value': 'admin2'
}
}
]
},
'functions': [{
'field_value_factor': {
'modifier': 'sqrt',
'field': 'popularity'
},
'weight': 1
}]
}
}]
}
}
}
},
'sort': [ '_sort' ],
'size': 10,
'track_scores': true
};

18
test/unit/query/search.js

@ -97,6 +97,24 @@ module.exports.tests.query = function(test, common) {
t.end();
});
test('search with viewport diagonal < 1km should set scale to 1km', function(t) {
var query = generate({
text: 'test', size: 10,
'focus.viewport.min_lat': 28.49135,
'focus.viewport.max_lat': 28.49137,
'focus.viewport.min_lon': -87.50622,
'focus.viewport.max_lon': -87.50624,
layers: ['test']
});
var compiled = JSON.parse( JSON.stringify( query ) );
var expected = require('../fixture/search_linguistic_viewport_min_diagonal');
expected.sort = sort;
t.deepEqual(compiled, expected, 'valid search query');
t.end();
});
test('search search + focus on null island', function(t) {
var query = generate({
text: 'test', size: 10,

Loading…
Cancel
Save