Add geo filtering for memory adapter

This commit is contained in:
Ritchie Martori 2013-06-24 15:21:59 -07:00
parent 008b406dd7
commit 6856ff7254
3 changed files with 88 additions and 1 deletions

View File

@ -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;

53
lib/geo.js Normal file
View File

@ -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 );
}

View File

@ -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);
}
}