var STARTED = false; var LOADING = false; var PROCESSING = false; var LOCALIZE_SESSION_ID = null; var device = null; var map = null; var boxes = {}; var ap_boxes = {}; var true_position_features = [] var est_position_features = [] var layers = {}; var boxStylesLookup = {}; var lastBoxCount = 0; var toBeProcessed = [] var BOX_OFFSET = 49 var sma5_process = simple_moving_averager(5) var sma5_load = simple_moving_averager(5) var avg_timeing = 50 var freeTime = 50 var numvisible = 100 POS_BOX_SIZE = 70 var true_last_pos = [0, 0] var est_last_pos = [0, 0] function createAPFeature(x, y, rssi){ var height = (100 + Math.round(rssi)) var bounds = new OpenLayers.Bounds(x, y, x + 10, y + height * 6); var feature = new OpenLayers.Feature.Vector(bounds.toGeometry(), {x: x, y: y}, boxStylesLookup[height*3+1]); layers['ap_vlayer'].addFeatures(feature); return feature } function createAPFeatures(){ $('span.apinfo').each(function(){ var apinfo = $(this) var apid = apinfo.attr('apid') var boxname = 'ap_' + apid var x = parseInt(apinfo.attr('x')) var y = parseInt(apinfo.attr('y')) var feature = createAPFeature(x, y, -100) ap_boxes[boxname + '_topcube'] = feature var feature = createAPFeature(x+15, y, -100) ap_boxes[boxname + '_measured'] = feature }) }; function adaptAPFeatures(apdata){ var old_features = [] $.each(apdata, function(i, apinfo){ var apid = apinfo[0] var ap_rssi = Math.max(apinfo[1], -100) var ap_rssi_measured = Math.max(apinfo[2], -100) var boxname = 'ap_' + apid $('span#api_' + apid).text(Math.round(ap_rssi) + '/' + Math.round(ap_rssi_measured)) var feature = ap_boxes[boxname + '_topcube'] old_features.push(feature); new_feature = createAPFeature(feature.data.x, feature.data.y, ap_rssi) ap_boxes[boxname + '_topcube'] = new_feature feature = ap_boxes[boxname + '_measured'] old_features.push(feature); new_feature = createAPFeature(feature.data.x, feature.data.y, ap_rssi_measured) ap_boxes[boxname + '_measured'] = new_feature }) layers['ap_vlayer'].destroyFeatures(old_features) }; function adaptTopN(data){ var maxcolor = 0 var mincolor = 10000000 var lonLat = new OpenLayers.LonLat(0, 0); $.each(data, function(i, loc){ avgidx = loc[2] if (avgidx > maxcolor){ maxcolor = avgidx }; if (avgidx < mincolor){ mincolor = avgidx }; }); var numcolors = parseInt($('span#rgbdata').attr('numcolors')) var color_ratio = (numcolors - 2) / (maxcolor - mincolor) var toBeAdded = []; $.each(data, function(i, loc){ var boxname = 'b'+i x = loc[0] y = loc[1] //~ costs = loc[2] //~ idx = loc[3] //~ avgcosts = loc[4] avgidx = loc[2] var color = numcolors - parseInt((avgidx - mincolor) * color_ratio) - 2 if (boxname in boxes){ var box = boxes[boxname]; lonLat.lon = x + BOX_OFFSET / 2 lonLat.lat = y + BOX_OFFSET / 2 box.feature.move(lonLat) //~ box.costs = costs layers['topn_vlayer'].drawFeature(box.feature, boxStylesLookup[color]); } else { var bounds = new OpenLayers.Bounds(x, y, x + BOX_OFFSET, y + BOX_OFFSET); var feature = new OpenLayers.Feature.Vector(bounds.toGeometry(), {id:boxname}, boxStylesLookup[color]); var box = { //~ costs : costs, feature : feature }; boxes[boxname] = box toBeAdded.push(feature) }; }); // delete var features = [] for (i=data.length; i < lastBoxCount; i=i+1){ var boxname = 'b'+i; features.push(boxes[boxname].feature) delete boxes[boxname]; } layers['topn_vlayer'].destroyFeatures(features) // add layers['topn_vlayer'].addFeatures(toBeAdded); lastBoxCount = data.length; } function drawPositionFeatures(position_features, pos, color, lastpos){ var x = pos[0] var y = pos[1] //var z = pos[2] if (position_features.length > 0){ var lastFeature = position_features[position_features.length-1] if ( Math.abs(lastpos[0] - x) < POS_BOX_SIZE && Math.abs(lastpos[1] - y) < POS_BOX_SIZE) { return } }; lastpos[0] = x lastpos[1] = y var bounds = new OpenLayers.Bounds(x, y, x + POS_BOX_SIZE, y + POS_BOX_SIZE); var style = {fillColor: color, strokeWidth: 0, strokeColor: color, 'fillOpacity': 0.8} var feature = new OpenLayers.Feature.Vector(bounds.toGeometry(), {}, style); layers['pos_vlayer'].addFeatures(feature); position_features.push(feature) var MAX_VISIBLE = 25 if (position_features.length > MAX_VISIBLE){ var f = position_features.shift() layers['pos_vlayer'].destroyFeatures(f) }; $.each(position_features, function(i, f){ style.fillOpacity = (i - 3 + (MAX_VISIBLE - position_features.length)) / MAX_VISIBLE layers['pos_vlayer'].drawFeature(f, style); }); }; function processData(){ if (toBeProcessed.length == 0 || PROCESSING){ setTimeout(processData, freeTime); return false } var start = new Date().getTime(); $('span#clientqueuesize').text(toBeProcessed.length) PROCESSING = true; data = toBeProcessed.shift() $('span#top_z').text(data.frame.z) $('span#pos_hight').text(data.frame.hight.toFixed(1)) if (layers['ap_vlayer'].getVisibility()){ adaptAPFeatures(data.frame.aps) }; if (layers['topn_vlayer'].getVisibility()){ adaptTopN(data.frame.topn) }; if (layers['pos_vlayer'].getVisibility()){ drawPositionFeatures(true_position_features, data.frame.pos, 'white', true_last_pos) drawPositionFeatures(est_position_features, data.frame.topn[data.frame.topn.length-1], 'red', est_last_pos) }; var end = new Date().getTime(); avg_timeing = sma5_process(end - start) setTimeout(processData, freeTime); PROCESSING = false return true } function loadData(){ if (LOADING){ return }; LOADING = true; var start_load = new Date().getTime(); $.getJSON("/locinfo/" + device + '/' + LOCALIZE_SESSION_ID + "/hmm/" + numvisible + '/1', function(response) { $('span#queuesize').text(start_load) $('span#queuesize').text('queuesize: ' + response['meta']['queuesize']) if (response['data'].length > 0){ //~ console.log('new data') } else { LOADING = false; return } //~ console.log(response['data'].length) toBeProcessed = [] $.each(response['data'], function(i, data){ toBeProcessed.push({'frame': data}) }); LOADING = false; var end_load = new Date().getTime(); avg_load_time = sma5_load(end_load - start_load) var totalFrames = response['data'].length freeTime = 1.5 * (avg_load_time + 300) - avg_timeing * totalFrames if (freeTime > 30){ freeTime = freeTime / totalFrames if (numvisible < 500){ numvisible = parseInt(numvisible * 1.1) }; } else if (freeTime < 0) { if (numvisible > 20){ numvisible = parseInt(numvisible * 0.9) }; freeTime = 10; } $('span#debug').text('visible:' + numvisible + ' delay:' + parseInt(freeTime) + 'ms') }); } OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, { defaultHandlerOptions: { 'single': true, 'double': false, 'pixelTolerance': 0, 'stopSingle': false, 'stopDouble': false }, initialize: function(options) { this.handlerOptions = OpenLayers.Util.extend( {}, this.defaultHandlerOptions ); OpenLayers.Control.prototype.initialize.apply( this, arguments ); this.handler = new OpenLayers.Handler.Click( this, { 'click': this.trigger }, this.handlerOptions ); }, trigger: function(e) { var lonlat = map.getLonLatFromViewPortPx(e.xy); $.get('/spawnSyntheticSignal/'+ device + '/' + lonlat.lon + '/' + lonlat.lat, function(response){ console.log(response) }) } }); $(document).ready(function() { device = $('div#stationinfo span#name').text() $.each($('span#rgbdata').text().split(','), function(i, v){ boxStylesLookup[i] = {fillColor: v, strokeWidth: 1, strokeColor: v}; //~ $('body').append(' ') }); var map_div = $("div#map"); areaWidth = 7808; areaHeight = 2432; imageDPI = 3.2512 // 16 * 8 pixel/meter OpenLayers.INCHES_PER_UNIT['pixels'] = 1 / imageDPI; var mapOptions = { controls: [], maxExtent: new OpenLayers.Bounds(0, 0, areaWidth, areaHeight), resolutions: [32, 16, 8, 4, 2, 1], numZoomLevels: 6, units: 'pixels', }; //create openlayers-map on div#map map = new OpenLayers.Map('map', mapOptions); scale = new OpenLayers.Control.ScaleLine({maxWidth:100, topInUnits:'m'}); map.addControl(scale); map.addControl(new OpenLayers.Control.Navigation()); layers['eg_layer'] = new OpenLayers.Layer.TMS( "2D Cut EG", "/tiles/", {layername: 'eg', type:'jpg', transitionEffect:'resize', 'isBaseLayer':true}) map.addLayer(layers['eg_layer']); layers['og1_layer'] = new OpenLayers.Layer.TMS( "2D Cut OG1", "/tiles/", {visibility: false, layername: 'og1', type:'jpg', transitionEffect:'resize', 'isBaseLayer':true}) map.addLayer(layers['og1_layer']); layers['og2_layer'] = new OpenLayers.Layer.TMS( "2D Cut OG2", "/tiles/", {visibility: false, layername: 'og2', type:'jpg', transitionEffect:'resize', 'isBaseLayer':true}) map.addLayer(layers['og2_layer']); currentZoomLevel = 2 lonLat = new OpenLayers.LonLat(3500, 1000); map.setCenter(lonLat, currentZoomLevel, 1, 1); layers['topn_vlayer'] = new OpenLayers.Layer.Vector( "Top N", {visibility: false, 'isBaseLayer':false}); map.addLayer(layers['topn_vlayer']); layers['ap_vlayer'] = new OpenLayers.Layer.Vector( "APs", {visibility: false, 'isBaseLayer':false}); map.addLayer(layers['ap_vlayer']); createAPFeatures() layers['pos_vlayer'] = new OpenLayers.Layer.Vector( "Position", {visibility: false, 'isBaseLayer':false}); map.addLayer(layers['pos_vlayer']); $('span.apid').each(function(i, e){ var apid = $(e).attr('apid') layers['aplayer_' + apid] = new OpenLayers.Layer.TMS( "APLayer_" + apid, "/apdatatiles/", {visibility: false, layername: device + ',' + apid, type:'png', transitionEffect:'resize', 'isBaseLayer':false, 'opacity': 0.8}) map.addLayer(layers['aplayer_' + apid]); }); //~ switcher = new OpenLayers.Control.LayerSwitcher(); //~ map.addControl(switcher); //~ switcher.maximizeControl(); var click = new OpenLayers.Control.Click(); map.addControl(click); //~ click.activate(); //~ return $.timer(300, function(timer){ if (STARTED && toBeProcessed.length <= 2){ loadData() }; }); setTimeout(processData, 1000); //update scale after zooming scale.update(); $('div#buttons div.baselayer').click(function(){ $('div#buttons div.baselayer').css('background-color', '#EEE') $('div#buttons div.baselayer').each(function(i, e){ layers[$(e).attr('layer')].setVisibility(false) }); $(this).css('background-color', '#CFC') layers[$(this).attr('layer')].setVisibility(true) map.setBaseLayer(layers[$(this).attr('layer')]); }); $('div#buttons div.layer').toggle(function(){ $(this).css('background-color', '#CFC') layers[$(this).attr('layer')].setVisibility(true) }, function(){ $(this).css('background-color', '#EEE') var l = layers[$(this).attr('layer')]; l.setVisibility(false) if ($(this).attr('layer') == 'pos_vlayer'){ $.each(true_position_features, function(i, f){ l.destroyFeatures(f) }); true_position_features = [] $.each(est_position_features, function(i, f){ l.destroyFeatures(f) }); est_position_features = [] }; }); $('div#buttons div#startstop').toggle(function(){ STARTED = true; var b = $(this) b.css('background-color','#FFE426') b.text('Starting...') LOCALIZE_SESSION_ID = parseInt(Math.random() * 1000000) $('span#session_id').text(LOCALIZE_SESSION_ID) $.get('/startLocalizeSession/' + device + '/' + LOCALIZE_SESSION_ID, function(){ b.css('background-color','#EE6644') b.text('Stop') }) }, function(){ STARTED = false; var b = $(this) b.css('background-color','#FFE426') b.text('Stopping...') $.get('/stopLocalizeSession/' + device + '/' + LOCALIZE_SESSION_ID, function(){ b.text('Start') b.css('background-color','#25BB25') }) }); $('span.apdisable').click(function(){ var apid = $(this).attr('apid'); if ($(this).hasClass('inactive_ap')){ $.get('/useAPforLocalizeDevice/' + device + '/' + apid + '/true'); } else { $.get('/useAPforLocalizeDevice/' + device + '/' + apid + '/false') }; $(this).toggleClass('inactive_ap') }); $('span.apid').click(function(){ var apid = $(this).attr('apid'); if ($(this).hasClass('show_ap_data')){ layers['aplayer_' + apid].setVisibility(false) } else { layers['aplayer_' + apid].setVisibility(true) }; $(this).toggleClass('show_ap_data') }); });