Mercurial > hg > STI-GWT
view war/scripts/sti/STICore.js @ 30:1e95995ddbb2
re-added the ability to refine the dataset by a (very simple) text search
author | Sebastian Kruse <skruse@mpiwg-berlin.mpg.de> |
---|---|
date | Wed, 28 Nov 2012 17:01:34 +0100 |
parents | 4711c4ab0c23 |
children | f635bbdc6a03 |
line wrap: on
line source
/** * defines the core component of the Spatio Temporal Interface * * @constructor */ function STICore(){ this.map; this.timeplot; this.refining; this.individualDataSet; this.takeTime; this.history; this.historyIndex; this.lockScreenContainer; this.initialize(); this.blocked = false; }; STICore.prototype = { blockUI: function(){ this.blocked = true; fullscreen.addFullscreen(fullscreen.loaderContent()); }, unblockUI: function(){ this.blocked = false; setTimeout( function(){ if( !this.blocked ){ setDefinedBounds(); } }, 150 ); fullscreen.removeFullscreen(); }, /** * refines the given data by creating a new history entry */ refine: function(){ if (this.refining > -2) { var contains = false; var newDataSets = []; var oldDataSets = this.history[this.historyIndex].dataSets; for (var i = 0; i < oldDataSets.length; i++) { var dataSet = oldDataSets[i].copy(); dataSet.source = oldDataSets[i].source; for (var j = 0; j < oldDataSets[i].objects.length; j++) { if ( oldDataSets[i].objects[j].percentage == 1 || this.refining > -1 && this.refining != i ){ dataSet.addObject( oldDataSets[i].objects[j] ); contains = true; } } newDataSets.push(dataSet); } if (contains) { this.addHistoryEntry( new HistoryEntry(newDataSets) ); this.reset(); this.initElements(); } else { alert("Your Selection contains no elements!"); } } else { alert("For Refining choose an Area on the map or a Range on the Timeplot!"); } return -1; }, /** * refines the given data by creating a new history entry */ refineByTime: function(minTime,maxTime){ var minDate = new Date(parseInt(minTime)); var maxDate = new Date(parseInt(maxTime)); if( this.timeplot.eds.minDate.getTime() == minDate.getTime() && this.timeplot.eds.maxDate.getTime() == maxDate.getTime() ){ return; } var newDataSets = []; var oldDataSets = this.history[this.historyIndex].dataSets; for (var i = 0; i < oldDataSets.length; i++) { var dataSet = oldDataSets[i].copy(); dataSet.source = oldDataSets[i].source; for (var j = 0; j < oldDataSets[i].objects.length; j++) { var o = oldDataSets[i].objects[j]; if( o.inTime(minDate,maxDate) ){ dataSet.addObject( o ); } } newDataSets.push(dataSet); } this.addHistoryEntry( new HistoryEntry(newDataSets) ); this.reset(); this.initElements(); }, /** * refines a given dataset by a given text snippet */ refineByText: function(text,index){ this.reset(); var dataset = this.history[this.historyIndex].dataSets[index]; for (var i = 0; i < dataset.objects.length; i++) { var e = dataset.objects[i]; if( e.name.toLowerCase().indexOf(text.toLowerCase()) != -1 ){ e.setPercentage(1); } } this.updateMapAndTimeAndTable(index); }, /** * adds selected elements of a specific dataset as a new dataset * * @param {int} * id the id of the dataset */ storeSelected: function(id){ var dataSets = this.history[this.historyIndex].dataSets; if( dataSets.length == 4 ){ alert( "The maximum number of 4 parallel datasets is reached!" ); } else { var dataSet = dataSets[id].copy(); var contains = false; for (var j = 0; j < dataSets[id].objects.length; j++) { if ( dataSets[id].objects[j].percentage == 1 ){ dataSet.addObject( dataSets[id].objects[j] ); contains = true; } } if (contains) { this.addDataSet(dataSet); } else { alert("Your Selection contains no elements!"); } } }, /** * Adds a dataset to the actual history entry */ addDataSet: function( dataSet ){ var oldDataSets = this.history[this.historyIndex].dataSets; var newDataSets = oldDataSets.concat(dataSet); this.addHistoryEntry(new HistoryEntry(newDataSets)); this.initElements(); this.reset(); }, /** * Sets the widgets for the core component * * @param {STIMap} * map the javascript object of the map widget * @param {STITimeplot} * plot the javascript object of the timeplot widget */ setElements: function(map, timeplot){ this.map = map; this.timeplot = timeplot; }, /** * initializes the core component for the Spatio Temporal Interface. here, * the handling of the search interface is defined (including undo, refine * and clear selection button). furthermore, the elements (map, timeplot, * tables) are instanciated. */ initialize: function(){ var context = this; this.takeTime = false; this.props = new STIProps(); this.history = []; this.history.push( new HistoryEntry([]) ); this.historyIndex = 0; var Unselectable = { enable: function(e){ var e = e ? e : window.event; if (e.button != 1) { if (e.target) { var targer = e.target; } else if (e.srcElement) { var targer = e.srcElement; } if( targer.tagName == undefined ){ return false; } var targetTag = targer.tagName.toLowerCase(); if ((targetTag != "input") && (targetTag != "textarea")) { return false; } } }, disable: function(){ return true; } } if (typeof(document.onselectstart) != "type filter textundefined") { document.onselectstart = Unselectable.enable; } else { document.onmousedown = Unselectable.enable; document.onmouseup = Unselectable.disable; } this.sources = []; try { var jsonString = this.getFileString("datasources.json"); this.sources = eval('(' + jsonString + ')'); } catch(e){ } this.lockScreenContainer = document.createElement("div"); this.lockScreenContainer.setAttribute('class','lockScreenContainer'); document.getElementById("mainContainer").appendChild(this.lockScreenContainer); }, getFileString: function(url){ var xmlhttp = false; if (!xmlhttp) try { xmlhttp = new XMLHttpRequest(); } catch (e) { xmlhttp = false; } if (typeof ActiveXObject != "undefined") { if (!xmlhttp) try { xmlhttp = new ActiveXObject("MSXML2.XMLHTTP"); } catch (e) { xmlhttp = false; } if (!xmlhttp) try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { xmlhttp = false; } } xmlhttp.open('GET', url, false); xmlhttp.send(""); return xmlhttp.responseText; }, /** * constructs an url to a dynamic datasource with the specific user input as * attribute * * @param {int} * ds the datasource index * @param {String} * input the user input */ retrieveKml: function(ds,input){ var url = this.sources[ds].url; // var tags = input.replace(/[^a-zA-Z0-9]/g,","); // url += tags; url += input; /* test for csv flag in request parameters (see datasources.json) */ var beginCsv = url.indexOf("csv=true"); if (beginCsv != -1) { /* remove "csv=true" from request parameters */ url = url.substr(0, beginCsv) + url.substr(beginCsv + 9); /* convert csv to kml */ this.parseCsv(url,input,ds); } else { /* parse kml */ this.parseKml(url,input,ds); } }, parseIt: function(xml,term,ds){ var getTimeData = function( timeString ){ try { var bc = false; if( timeString.startsWith("-") ){ bc = true; timeString = timeString.substring(1); } var timeSplit = timeString.split("T"); var timeData = timeSplit[0].split("-"); for (var i = 0; i < timeData.length; i++) { parseInt(timeData[i]); } if( bc ){ timeData[0] = "-"+timeData[0]; } if (timeSplit.length == 1) { return timeData; } var dayData; if (timeSplit[1].indexOf("Z") != -1) { dayData = timeSplit[1].substring(0, timeSplit[1].indexOf("Z") - 1).split(":"); } else { dayData = timeSplit[1].substring(0, timeSplit[1].indexOf("+") - 1).split(":"); } for (var i = 0; i < timeData.length; i++) { parseInt(dayData[i]); } return timeData.concat(dayData); } catch (exception) { return null; } } var time = SimileAjax.DateTime; var newObjects = new Array(); var elements = xml.getElementsByTagName("Placemark"); var granularity = 0; if( elements.length == 0 ){ this.unblockUI(); return; } for (var i = 0; i < elements.length; i++) { var placemark = elements[i]; var name, description, place, timeData, coordinates, timeStamp, timeSpan, g; try{ var nameElement = placemark.getElementsByTagName("name"); if ( (nameElement != null) && (nameElement.length > 0) && (nameElement[0].childNodes.length > 0) ){ name = nameElement[0].childNodes[0].nodeValue; } else { name = ""; } } catch(e) { name = ""; } try{ var descriptionElement = placemark.getElementsByTagName("description"); if ( (descriptionElement != null) && (descriptionElement.length > 0) && (descriptionElement[0].childNodes.length > 0) ){ description = descriptionElement[0].childNodes[0].nodeValue; } else { description = ""; } } catch(e) { description = ""; } try{ var placeElement = placemark.getElementsByTagName("address"); if ( (placeElement != null) && (placeElement.length > 0) && (placeElement[0].childNodes.length > 0) ){ place = placeElement[0].childNodes[0].nodeValue; } else { place = ""; } } catch(e) { place = ""; } var getDate = function(timeData){ var date; if (timeData.length == 6) { g = time.SECOND; date = new Date(Date.UTC(timeData[0], timeData[1]-1, timeData[2], timeData[3], timeData[4], timeData[5])); } else if (timeData.length == 3) { g = time.DAY; date = new Date(Date.UTC(timeData[0], timeData[1]-1, timeData[2])); } else if (timeData.length == 2) { g = time.MONTH; date = new Date(Date.UTC(timeData[0], timeData[1]-1, 1)); } else if (timeData.length == 1) { g = time.YEAR; date = new Date(Date.UTC(timeData[0], 0, 1)); } if (granularity < g) { granularity = g; } if( timeData[0] && timeData[0] < 100 ){ date.setFullYear(timeData[0]); } return date; } try { timeData = getTimeData( placemark.getElementsByTagName("TimeStamp")[0].getElementsByTagName("when")[0].childNodes[0].nodeValue ); if( timeData != null ){ timeStamp = getDate(timeData); } if( timeStamp == undefined ){ continue; } } catch(e){ try { timeStamp = undefined; var timeSpanTag = placemark.getElementsByTagName("TimeSpan")[0]; var timeDataStart = getTimeData( timeSpanTag.getElementsByTagName("begin")[0].childNodes[0].nodeValue ); var startTime = getDate(timeDataStart); var timeDataEnd = getTimeData( timeSpanTag.getElementsByTagName("end")[0].childNodes[0].nodeValue ); var endTime = getDate(timeDataEnd); timeSpan = { start: startTime, end: endTime }; } catch(e){ continue; } } try { coordinates = placemark.getElementsByTagName("Point")[0].getElementsByTagName("coordinates")[0].childNodes[0].nodeValue; var lonlat = coordinates.split(","); if( lonlat[0] == "" || lonlat[1] == "" || isNaN(lonlat[0]) || isNaN(lonlat[1]) ){ continue; } newObjects.push(new DataObject(name, description, place, timeStamp, timeSpan, g, lonlat[0], lonlat[1])); } catch(e){ continue; } } var dataset = new DataSet( newObjects, term, granularity ); dataset.source = ds; var core = this; var status = document.getElementById("statusText"); status.innerHTML = "Space & Time Aggregation ..."; setTimeout( function(){ core.addDataSet( dataset ); core.unblockUI(); }, 1 ); }, /** * parses the kml-file which includes the results for a given search request * * @param {File} * kmlFile * @param {String} * term the term identifier for the resulting dataset */ parseKml: function(kmlFile,term,ds){ var core = this; if( this.blocked ){ setTimeout( function(){ core.parseKml(kmlFile,term,ds); }, 100 ); return; } core.blockUI(); $.ajax({ url: kmlFile, dataType: "xml", beforeSend: function(){ var status = document.getElementById("statusText"); status.innerHTML = "Retrieving Data ..."; }, success: function(xml){ var status = document.getElementById("statusText"); status.innerHTML = "Parsing Data ..."; setTimeout( function(){ core.parseIt(xml,term,ds); }, 1 ); } }); }, /** * converts the csv-file, then parses the kml-file which includes the * results for a given search request * * @param {File} * csvFile * @param {String} * term the term identifier for the resulting dataset */ parseCsv: function(csvFile,term,ds){ var core = this; if( this.blocked ){ setTimeout( function(){ core.parseCsv(csvFile,term,ds); }, 100 ); return; } core.blockUI(); $.ajax({ url: csvFile, dataType: "text", beforeSend: function(){ var status = document.getElementById("statusText"); status.innerHTML = "Retrieving Data ..."; }, success: function(text){ var status = document.getElementById("statusText"); status.innerHTML = "Converting CSV to KML ..."; /* convert here from csv to kml */ var kmlString = '<?xml version="1.0" standalone="yes"?>\n'; kmlString += '<kml xmlns="http://www.opengis.com/kml/ext/2.2">\n'; kmlString += '\t<Folder>\n'; /* define expected csv table headers (first line) */ var expectedHeaders = new Array("Name","Address","Description","Longitude","Latitude","TimeStamp","TimeSpan:begin","TimeSpan:end"); /* convert csv string to array of arrays using ucsv library */ var csvArray = CSV.csvToArray(text); /* get real used table headers from csv file (first line) */ var usedHeaders = csvArray[0]; /* loop outer array, begin with second line */ for (var i = 1; i < csvArray.length; i++) { var innerArray = csvArray[i]; kmlString += '\t\t<Placemark>\n'; /* declare few variables */ var timespanBegin = ""; var timespanEnd = ""; var longitude = ""; var latitude = ""; /* loop inner array */ for (var j = 0; j < innerArray.length; j++) { /* Name */ if (usedHeaders[j] == expectedHeaders[0]) { kmlString += '\t\t\t<name>' + innerArray[j] + '</name>\n'; } /* Address */ if (usedHeaders[j] == expectedHeaders[1]) { kmlString += '\t\t\t<address>' + innerArray[j] + '</address>\n'; } /* Description */ if (usedHeaders[j] == expectedHeaders[2]) { kmlString += '\t\t\t<description>' + innerArray[j] + '</description>\n'; } /* TimeStamp */ if (usedHeaders[j] == expectedHeaders[5]) { kmlString += '\t\t\t<TimeStamp>\n' + '\t\t\t\t<when>' + innerArray[j] + '</when>\n' + '\t\t\t</TimeStamp>\n'; } /* TimeSpan:begin */ if (usedHeaders[j] == expectedHeaders[6]) { timespanBegin = innerArray[j]; } /* TimeSpan:end */ if (usedHeaders[j] == expectedHeaders[7]) { timespanEnd = innerArray[j]; } /* Longitude */ if (usedHeaders[j] == expectedHeaders[3]) { longitude = innerArray[j]; } /* Latitude */ if (usedHeaders[j] == expectedHeaders[4]) { latitude = innerArray[j]; } } /* set timespan:begin und timespan:end */ kmlString += '\t\t\t<TimeSpan>\n' + '\t\t\t\t<begin>' + timespanBegin + '</begin>\n' + '\t\t\t\t<end>' + timespanEnd + '</end>\n' + '\t\t\t</TimeSpan>\n'; /* set longitude and latitude */ kmlString += '\t\t\t<Point>\n' + '\t\t\t\t<coordinates>' + longitude +',' + latitude + '</coordinates>\n' + '\t\t\t</Point>\n'; /* end Placemark */ kmlString += '\t\t</Placemark>\n'; } kmlString += '\t</Folder>\n'; kmlString += '</kml>\n'; console.log("kmlstring="+kmlString); /* convert string to xml */ var kmlXml = $.parseXML(kmlString); console.log(kmlXml); /* pares the converted kml data */ var status = document.getElementById("statusText"); status.innerHTML = "Parsing Data ..."; setTimeout( function(){ core.parseIt(kmlXml,term,ds); }, 1 ); } }); }, /** * updates the timeplot and table element. its called from the STIMap * object, when objects on the map had been selected by featureSelect or * polygon. * * @param {boolean} * hover true, if there was a hover selection */ updateTimeAndTable: function(hover){ updateTables(hover); this.timeplot.polesBySlices(); this.refining = -1; }, /** * updates the map, timeplot and table element. its called from the STITable * object, when a text selection has been done */ updateMapAndTimeAndTable: function(index){ updateTables(hover); this.timeplot.polesBySlices(); this.map.updateMap(); this.refining = index; }, /** * updates the timeplot and map element. its called from the STITable * object, when objects in one of the tables had been selected. */ updateTimeAndMap: function(){ this.map.updateMap(); this.timeplot.polesBySlices(); this.refining = -1; }, /** * updates the table and map element. its called from the STITimeplot * object, when objects in the timeplot had been selected by timestamp or * -range. * * @param {boolean} * hover true, if there was a hover selection */ updateTableAndMap: function(hover){ updateTables(hover); this.map.updateMap(); this.refining = -1; }, /** * initializes the sti components (map, timeplot, table) depending on the * top masks of the data sets. its called after a new search was performed, * refining or undo button had been clicked */ initElements: function(){ this.reset(); var dataSets = this.history[this.historyIndex].dataSets; var granularity = 0; for( var i=0; i<dataSets.length; i++ ){ if( dataSets[i].maxGranularity > granularity ){ granularity = dataSets[i].maxGranularity; } } this.timeplot.initTimeplot(dataSets, granularity); this.map.initObjectLayer(dataSets); initTables(); }, /** * deletes a data set with specific index * * @param {int} * index the index of the data set to delete */ deleteDataSet: function(index){ var color = colors[index]; colors.splice(index, 1); var oldDataSets = this.history[this.historyIndex].dataSets; var newDataSets = []; for( var i=0; i<oldDataSets.length; i++ ){ if( i != index ){ newDataSets.push( oldDataSets[i] ); } } colors.splice( newDataSets.length, 0, color ); this.addHistoryEntry(new HistoryEntry(newDataSets)); this.initElements(); this.reset(); }, /** * Switches to another history entry with the given index * * @param {int} * index the index of the history entry to load */ switchThroughHistory: function( index ){ this.historyIndex = index; this.initElements(); }, /** * Adds a new history entry containing actual datasets * * @param {HistoryEntry} * historyEntry the history entry to add */ addHistoryEntry: function( historyEntry ){ this.history = this.history.slice(0,this.historyIndex+1); this.history.push(historyEntry); this.historyIndex = this.history.length - 1; addHistoryItem(this.historyIndex); }, /** * adds an element to the user individual data set * * @param {DataObject} * object the data object to add */ addElement: function(object){ if (this.individualDataSet == null) { this.individualDataSet = new DataSet([], "individual", 0); var oldDataSets = this.history[this.historyIndex].dataSets; var newDataSets = oldDataSets.concat(this.individualDataSet); this.addHistoryEntry(new HistoryEntry(newDataSets)); } this.individualDataSet.addObject(object); this.initElements(); this.reset(); }, /** * resets the core within all elements and data objects to * non-selection-status */ reset: function(){ this.refining = -2; var dataSets = this.history[this.historyIndex].dataSets; for (var i = 0; i < dataSets.length; i++){ for (var j = 0; j < dataSets[i].objects.length; j++){ dataSets[i].objects[j].setPercentage(0); dataSets[i].objects[j].setHover(false); } } this.timeplot.resetTimeplot(); this.map.resetMap(); updateTables(false); }, /** * Security hover unselection of elements if browser events got stucked */ undoHover: function(update){ this.map.hoverUnselect(); this.timeplot.hoverUnselect(update); }, createLink: function(){ var c = this.map.openlayersMap.getCenter(); var map = this.map.openlayersMap.baseLayer.id; var mapCenter = { lon: c.lon, lat: c.lat }; var mapZoom = this.map.openlayersMap.getZoom(); var data = []; // store complete history in data --> flow of history events // history event can be: loading/deleting dataset, refinement by // timerange/polygon at specific zoom level/point at specific zoom // level, a loaded link history (this) // flag for the ability to display stored history or not }, lockScreen: function(){ this.lockScreenContainer.style.visibility = "visible"; this.lockScreenContainer.style.height = getDocHeight()+"px"; }, lockScreenMessage: function(div){ this.lockScreenContainer.innerHTML = ""; var lockScreenDiv = document.createElement("div"); lockScreenDiv.setAttribute('class','lockScreen'); this.lockScreenContainer.appendChild(lockScreenDiv); this.lockScreenContainer.appendChild(div); }, unlockScreen: function(){ this.lockScreenContainer.style.visibility = "hidden"; } }; /** * defines a history entry * * @param {DataSet[]} * dataSets the datasets of this history entry * * @constructor */ function HistoryEntry( dataSets ){ this.dataSets = dataSets; };