Add geo filtering for memory adapter
This commit is contained in:
parent
008b406dd7
commit
6856ff7254
|
@ -1,3 +1,5 @@
|
|||
var geo = require('../geo');
|
||||
|
||||
exports.initialize = function initializeSchema(schema, callback) {
|
||||
schema.adapter = new Memory();
|
||||
schema.adapter.connect(callback);
|
||||
|
@ -108,9 +110,10 @@ Memory.prototype.all = function all(model, filter, callback) {
|
|||
var nodes = Object.keys(this.cache[model]).map(function (key) {
|
||||
return this.fromDb(model, this.cache[model][key]);
|
||||
}.bind(this));
|
||||
var isGeo = false;
|
||||
|
||||
|
||||
if (filter) {
|
||||
|
||||
// do we need some sorting?
|
||||
if (filter.order) {
|
||||
var props = this._models[model].properties;
|
||||
|
@ -129,6 +132,13 @@ Memory.prototype.all = function all(model, filter, callback) {
|
|||
});
|
||||
nodes = nodes.sort(sorting.bind(orders));
|
||||
}
|
||||
|
||||
var nearFilter = nearFilter(filter.where);
|
||||
|
||||
// geo sorting
|
||||
if(nearFilter) {
|
||||
nodes = geo.filter(nodes, nearFilter);
|
||||
}
|
||||
|
||||
// do we need some filtration?
|
||||
if (filter.where) {
|
||||
|
@ -160,6 +170,26 @@ Memory.prototype.all = function all(model, filter, callback) {
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function nearFilter(where) {
|
||||
var result = false;
|
||||
|
||||
if(where && typeof where === 'object') {
|
||||
Object.keys(where).forEach(function (key) {
|
||||
var ex = where[key];
|
||||
|
||||
if(ex && ex.near) {
|
||||
result = {
|
||||
near: ex.near,
|
||||
maxDistance: ex.maxDistance,
|
||||
key: key
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
function applyFilter(filter) {
|
||||
|
@ -191,6 +221,7 @@ function applyFilter(filter) {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if(isNum(example.gt) && example.gt < value) return true;
|
||||
if(isNum(example.gte) && example.gte <= value) return true;
|
||||
if(isNum(example.lt) && example.lt > value) return true;
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
exports.filter = function (arr, filter) {
|
||||
var origin = filter.near;
|
||||
var max = filter.maxDistance > 0 ? filter.maxDistance : false;
|
||||
var key = filter.key;
|
||||
|
||||
// create distance index
|
||||
var distances = {};
|
||||
var result = [];
|
||||
|
||||
arr.forEach(function (obj) {
|
||||
var loc = obj[key];
|
||||
|
||||
// filter out objects without locations
|
||||
if(!loc) return;
|
||||
if(typeof loc.lat !== 'number') return;
|
||||
if(typeof loc.long !== 'number') return;
|
||||
|
||||
var d = distanceBetween(origin, loc);
|
||||
|
||||
if(max && d > max) {
|
||||
// dont add
|
||||
} else {
|
||||
distances[obj.id] = d;
|
||||
result.push(obj);
|
||||
}
|
||||
});
|
||||
|
||||
return result.sort(function (objA, objB) {
|
||||
var a = objB[key];
|
||||
var b = objB[key];
|
||||
|
||||
if(a && b) {
|
||||
var da = distances[objA.id];
|
||||
var db = distances[objB.id];
|
||||
|
||||
if(db === da) return 0;
|
||||
return da > db ? -1 : 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var distanceBetween = exports.distanceBetween = function distanceBetween(a, b) {
|
||||
var xs = 0;
|
||||
var ys = 0;
|
||||
xs = a.lat - b.lat;
|
||||
xs = xs * xs;
|
||||
ys = a.long - b.long;
|
||||
ys = ys * ys;
|
||||
|
||||
return Math.sqrt( xs + ys );
|
||||
}
|
|
@ -215,6 +215,9 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
|
|||
if (value === null || value === undefined) {
|
||||
this.__data[attr] = value;
|
||||
} else {
|
||||
if(attr === 'geo') {
|
||||
debugger;
|
||||
}
|
||||
this.__data[attr] = DataType(value);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue