这是我正在尝试做的事情,并且悲惨地失败了:
我的MongoDB充满了连接到汽车的设备的GPS读数。读数带有时间戳,并有一个lat / lng。
对于每次阅读,我想创建一个包含位置,时间戳和其他信息的Position类。
要在Google地图上绘制此图,我想创建一个Route类,它由一组Positions Objects组成。
顶部的main函数从示例JSON文件加载路径(以避免CSRF问题......另一个故事),创建Position对象并路由对象。当我尝试绘制路线时,问题就开始了。
var positions = this.getPositions();
如果我输入
console.log(positions);
在该行的正下方,它将打印位置数组正常。这需要一点点,因为它很大,但它的工作原理。
但是,如果我输入
console.log(positions[0]);
它不会起作用,因为这些位置还没有加载。
我该怎么办?
我正在使用http://classy.pocoo.org中的classy.js,但我已经证实这不是问题。
function main()
{
var route = Route('20120928_025650_0');
route.plot();
}
var Route = Class.$extend({
__init__ : function(imaging_run_id) {
this.imaging_run_id = imaging_run_id;
this.positions = [];
this.load();
},
getPositions : function() {
return (this.positions);
},
load : function() {
//var url='http://localhost:5001/gps/by_imaging_run_id/' + this.imaging_run_id;
var test_url = '/static/20120928_025650_0.json';
var me = this;
$.getJSON(test_url, function(route) {
for(var position in route) {
var obj = route[position];
var new_position = Position(obj['_id'], obj['lat'], obj['lng'], obj['timestamp'], obj['epoch_timestamp'], obj['is_valid']);
me.pushPositions(new_position);
}
me.orderPositions();
})
.error(function(jqXhr, textStatus, error) {
alert("ERROR: " + textStatus + ", " + error);
});
},
orderPositions : function() {
var unsorted_array = this.getPositions();
var sorted = unsorted_array.sort(function(a,b){ //Custom sort function
return a['timestamp'] - b['timestamp']; //Sort ascending
});
this.setPositions(sorted);
},
plot : function() {
var positions = this.getPositions();
var points = [];
var bounds = new google.maps.LatLngBounds();
for(var i=0; i<positions.length; i++)
{
var obj = positions[i];
var point = new google.maps.LatLng(obj['location'][0], obj['location'][1]);
points.push(point);
bounds.extend(point);
}
// Create the polyline.
var route = new google.maps.Polyline({
path: points,
strokeColor: '#e81971',
strokeOpacity: 1.0,
strokeWeight: 4
});
map.fitBounds(bounds);
route.setMap(map);
}
});
var Position = Class.$extend({
__init__ : function(id, lat, lng, timestamp, epoch_timestamp, valid) {
this.id = id;
this.location = [lat, lng];
this.timestamp = new Date(timestamp);
this.epoch_timestamp = new Date(epoch_timestamp);
this.valid = valid;
this.anchor_location;
},.....
答案 0 :(得分:3)
如果我理解正确,你会想做这样的事情:
var positions = this.getPositions(function(positions) {
console.log(positions[0]);
});
也就是说,你想要以接受单个回调参数的方式编写“getPositions”,一旦位置成功加载就调用该参数,并传递位置数组。在getPositions
中,您可以检查位置是否已经加载,如果已加载,则直接调用回调。否则,你将它们添加到一个回调队列(例如this.positionsLoadedCallbacks
),在你加载所有位置之后迭代它(我认为这将在load
函数附近的某个位置{{1 }})。
例如,您的me.orderPositions()
函数可能如下所示:
getPositions
在您确定已加载位置(即在loadJSON成功回调中)后,您需要输入以下内容:
getPositions : function(callback) {
if(this.positions !== null) {
callback(this.positions);
return;
}
this.positionsLoadedCallbacks.push(callback);
},
不要忘记初始化for(var i=0; i < this.positionsLoadedCallbacks.length; i++) {
this.positionsLoadedCallbacks[i](this.positions);
}
:)
this.positionsLoadedCallbacks
的工作原理和console.log(positions)
并不容易:如果您将对象引用传递给console.log(positions[0])
,则在点击“扩展”时会检查对象箭头并试着看看里面的对象/数组。当你点击那个箭头时,当然已经加载了这些位置。但是,如果您传递特定的数组元素(例如console.log
),它将直接尝试查找该值,发现它仍然是positions[0]
,并将该结果记录在控制台中。
亲自尝试:
undefined
Chrome 24中的上一个代码段在控制台中显示var i = [];
console.log([i]);
i.push(123);
,但是当我展开它时,它会告诉我该数组为[Array[0]]
且其第一个元素为length: 1