Mercurial > hg > STI-GWT
comparison war/scripts/sti/STICore.js @ 3:cf06b77a8bbd
Committed branch of the e4D repos sti-gwt branch 16384.
git-svn-id: http://dev.dariah.eu/svn/repos/eu.dariah.de/ap1/sti-gwt-dariah-geobrowser@36 f2b5be40-def6-11e0-8a09-b3c1cc336c6b
author | StefanFunk <StefanFunk@f2b5be40-def6-11e0-8a09-b3c1cc336c6b> |
---|---|
date | Tue, 17 Jul 2012 13:34:40 +0000 |
parents | |
children | 517a6422d1bd |
comparison
equal
deleted
inserted
replaced
2:2897af43ccc6 | 3:cf06b77a8bbd |
---|---|
1 /** | |
2 * defines the core component of the Spatio Temporal Interface | |
3 * | |
4 * @constructor | |
5 */ | |
6 function STICore(){ | |
7 | |
8 this.map; | |
9 this.timeplot; | |
10 | |
11 this.refining; | |
12 this.individualDataSet; | |
13 | |
14 this.takeTime; | |
15 | |
16 this.history; | |
17 this.historyIndex; | |
18 this.lockScreenContainer; | |
19 | |
20 this.initialize(); | |
21 this.blocked = false; | |
22 | |
23 }; | |
24 | |
25 STICore.prototype = { | |
26 | |
27 blockUI: function(){ | |
28 this.blocked = true; | |
29 fullscreen.addFullscreen(fullscreen.loaderContent()); | |
30 }, | |
31 | |
32 unblockUI: function(){ | |
33 this.blocked = false; | |
34 setTimeout( function(){ if( !this.blocked ){ setDefinedBounds(); } }, 150 ); | |
35 fullscreen.removeFullscreen(); | |
36 }, | |
37 | |
38 /** | |
39 * refines the given data by creating a new history entry | |
40 */ | |
41 refine: function(){ | |
42 if (this.refining > -2) { | |
43 var contains = false; | |
44 var newDataSets = []; | |
45 var oldDataSets = this.history[this.historyIndex].dataSets; | |
46 for (var i = 0; i < oldDataSets.length; i++) { | |
47 var dataSet = oldDataSets[i].copy(); | |
48 dataSet.source = oldDataSets[i].source; | |
49 for (var j = 0; j < oldDataSets[i].objects.length; j++) { | |
50 if ( oldDataSets[i].objects[j].percentage == 1 || this.refining > -1 && this.refining != i ){ | |
51 dataSet.addObject( oldDataSets[i].objects[j] ); | |
52 contains = true; | |
53 } | |
54 } | |
55 newDataSets.push(dataSet); | |
56 } | |
57 if (contains) { | |
58 this.addHistoryEntry( new HistoryEntry(newDataSets) ); | |
59 this.reset(); | |
60 this.initElements(); | |
61 } | |
62 else { | |
63 alert("Your Selection contains no elements!"); | |
64 } | |
65 } | |
66 else { | |
67 alert("For Refining choose an Area on the map or a Range on the Timeplot!"); | |
68 } | |
69 return -1; | |
70 }, | |
71 | |
72 /** | |
73 * refines the given data by creating a new history entry | |
74 */ | |
75 refineByTime: function(minTime,maxTime){ | |
76 var minDate = new Date(parseInt(minTime)); | |
77 var maxDate = new Date(parseInt(maxTime)); | |
78 if( this.timeplot.eds.minDate.getTime() == minDate.getTime() && | |
79 this.timeplot.eds.maxDate.getTime() == maxDate.getTime() ){ | |
80 return; | |
81 } | |
82 var newDataSets = []; | |
83 var oldDataSets = this.history[this.historyIndex].dataSets; | |
84 for (var i = 0; i < oldDataSets.length; i++) { | |
85 var dataSet = oldDataSets[i].copy(); | |
86 dataSet.source = oldDataSets[i].source; | |
87 for (var j = 0; j < oldDataSets[i].objects.length; j++) { | |
88 var o = oldDataSets[i].objects[j]; | |
89 if( o.inTime(minDate,maxDate) ){ | |
90 dataSet.addObject( o ); | |
91 } | |
92 } | |
93 newDataSets.push(dataSet); | |
94 } | |
95 this.addHistoryEntry( new HistoryEntry(newDataSets) ); | |
96 this.reset(); | |
97 this.initElements(); | |
98 }, | |
99 | |
100 /** | |
101 * refines a given dataset by a given text snippet | |
102 */ | |
103 refineByText: function(text,index){ | |
104 this.reset(); | |
105 var dataset = this.history[this.historyIndex].dataSets[index]; | |
106 for (var i = 0; i < dataset.objects.length; i++) { | |
107 var e = dataset.objects[i]; | |
108 if( e.name.toLowerCase().indexOf(text.toLowerCase()) != -1 ){ | |
109 e.setPercentage(1); | |
110 } | |
111 } | |
112 this.updateMapAndTimeAndTable(index); | |
113 }, | |
114 | |
115 /** | |
116 * adds selected elements of a specific dataset as a new dataset | |
117 * @param {int} id the id of the dataset | |
118 */ | |
119 storeSelected: function(id){ | |
120 var dataSets = this.history[this.historyIndex].dataSets; | |
121 if( dataSets.length == 4 ){ | |
122 alert( "The maximum number of 4 parallel datasets is reached!" ); | |
123 } | |
124 else { | |
125 var dataSet = dataSets[id].copy(); | |
126 var contains = false; | |
127 for (var j = 0; j < dataSets[id].objects.length; j++) { | |
128 if ( dataSets[id].objects[j].percentage == 1 ){ | |
129 dataSet.addObject( dataSets[id].objects[j] ); | |
130 contains = true; | |
131 } | |
132 } | |
133 if (contains) { | |
134 this.addDataSet(dataSet); | |
135 } | |
136 else { | |
137 alert("Your Selection contains no elements!"); | |
138 } | |
139 } | |
140 }, | |
141 | |
142 /** | |
143 * Adds a dataset to the actual history entry | |
144 */ | |
145 addDataSet: function( dataSet ){ | |
146 var oldDataSets = this.history[this.historyIndex].dataSets; | |
147 var newDataSets = oldDataSets.concat(dataSet); | |
148 this.addHistoryEntry(new HistoryEntry(newDataSets)); | |
149 this.initElements(); | |
150 this.reset(); | |
151 }, | |
152 | |
153 /** | |
154 * Sets the widgets for the core component | |
155 * | |
156 * @param {STIMap} map the javascript object of the map widget | |
157 * @param {STITimeplot} plot the javascript object of the timeplot widget | |
158 */ | |
159 setElements: function(map, timeplot){ | |
160 this.map = map; | |
161 this.timeplot = timeplot; | |
162 }, | |
163 | |
164 /** | |
165 * initializes the core component for the Spatio Temporal Interface. | |
166 * here, the handling of the search interface is defined (including undo, refine and clear selection button). | |
167 * furthermore, the elements (map, timeplot, tables) are instanciated. | |
168 */ | |
169 initialize: function(){ | |
170 | |
171 var context = this; | |
172 this.takeTime = false; | |
173 this.props = new STIProps(); | |
174 | |
175 this.history = []; | |
176 | |
177 this.history.push( new HistoryEntry([]) ); | |
178 this.historyIndex = 0; | |
179 | |
180 var Unselectable = { | |
181 enable: function(e){ | |
182 var e = e ? e : window.event; | |
183 if (e.button != 1) { | |
184 if (e.target) { | |
185 var targer = e.target; | |
186 } | |
187 else | |
188 if (e.srcElement) { | |
189 var targer = e.srcElement; | |
190 } | |
191 if( targer.tagName == undefined ){ | |
192 return false; | |
193 } | |
194 var targetTag = targer.tagName.toLowerCase(); | |
195 if ((targetTag != "input") && (targetTag != "textarea")) { | |
196 return false; | |
197 } | |
198 } | |
199 }, | |
200 disable: function(){ | |
201 return true; | |
202 } | |
203 } | |
204 | |
205 if (typeof(document.onselectstart) != "type filter textundefined") { | |
206 document.onselectstart = Unselectable.enable; | |
207 } | |
208 else { | |
209 document.onmousedown = Unselectable.enable; | |
210 document.onmouseup = Unselectable.disable; | |
211 } | |
212 | |
213 this.sources = []; | |
214 try { | |
215 var jsonString = this.getFileString("datasources.json"); | |
216 this.sources = eval('(' + jsonString + ')'); | |
217 } | |
218 catch(e){ | |
219 } | |
220 | |
221 this.lockScreenContainer = document.createElement("div"); | |
222 this.lockScreenContainer.setAttribute('class','lockScreenContainer'); | |
223 document.getElementsByTagName("body")[0].appendChild(this.lockScreenContainer); | |
224 | |
225 }, | |
226 | |
227 getFileString: function(url){ | |
228 var xmlhttp = false; | |
229 if (!xmlhttp) | |
230 try { | |
231 xmlhttp = new XMLHttpRequest(); | |
232 } | |
233 catch (e) { | |
234 xmlhttp = false; | |
235 } | |
236 if (typeof ActiveXObject != "undefined") { | |
237 if (!xmlhttp) | |
238 try { | |
239 xmlhttp = new ActiveXObject("MSXML2.XMLHTTP"); | |
240 } | |
241 catch (e) { | |
242 xmlhttp = false; | |
243 } | |
244 if (!xmlhttp) | |
245 try { | |
246 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); | |
247 } | |
248 catch (e) { | |
249 xmlhttp = false; | |
250 } | |
251 } | |
252 xmlhttp.open('GET', url, false); | |
253 xmlhttp.send(""); | |
254 return xmlhttp.responseText; | |
255 }, | |
256 | |
257 /** | |
258 * constructs an url to a dynamic datasource with the specific user input as attribute | |
259 * @param {int} ds the datasource index | |
260 * @param {String} input the user input | |
261 */ | |
262 retrieveKml: function(ds,input){ | |
263 var url = this.sources[ds].url; | |
264 // var tags = input.replace(/[^a-zA-Z0-9]/g,","); | |
265 // url += tags; | |
266 url += input; | |
267 this.parseKml(url,input,ds); | |
268 }, | |
269 | |
270 parseIt: function(xml,term,ds){ | |
271 var getTimeData = function( timeString ){ | |
272 try { | |
273 var bc = false; | |
274 if( timeString.startsWith("-") ){ | |
275 bc = true; | |
276 timeString = timeString.substring(1); | |
277 } | |
278 var timeSplit = timeString.split("T"); | |
279 var timeData = timeSplit[0].split("-"); | |
280 for (var i = 0; i < timeData.length; i++) { | |
281 parseInt(timeData[i]); | |
282 } | |
283 if( bc ){ | |
284 timeData[0] = "-"+timeData[0]; | |
285 } | |
286 if (timeSplit.length == 1) { | |
287 return timeData; | |
288 } | |
289 var dayData; | |
290 if (timeSplit[1].indexOf("Z") != -1) { | |
291 dayData = timeSplit[1].substring(0, timeSplit[1].indexOf("Z") - 1).split(":"); | |
292 } | |
293 else { | |
294 dayData = timeSplit[1].substring(0, timeSplit[1].indexOf("+") - 1).split(":"); | |
295 } | |
296 for (var i = 0; i < timeData.length; i++) { | |
297 parseInt(dayData[i]); | |
298 } | |
299 return timeData.concat(dayData); | |
300 } | |
301 catch (exception) { | |
302 return null; | |
303 } | |
304 } | |
305 | |
306 var time = SimileAjax.DateTime; | |
307 var newObjects = new Array(); | |
308 var elements = xml.getElementsByTagName("Placemark"); | |
309 var granularity = 0; | |
310 | |
311 if( elements.length == 0 ){ | |
312 this.unblockUI(); | |
313 return; | |
314 } | |
315 | |
316 for (var i = 0; i < elements.length; i++) { | |
317 | |
318 var placemark = elements[i]; | |
319 var name, description, place, timeData, coordinates, timeStamp, timeSpan, g; | |
320 | |
321 try { | |
322 name = placemark.getElementsByTagName("name")[0].childNodes[0].nodeValue; | |
323 } | |
324 catch(e){ | |
325 name = ""; | |
326 } | |
327 | |
328 try { | |
329 description = placemark.getElementsByTagName("description")[0].childNodes[0].nodeValue; | |
330 } | |
331 catch(e){ | |
332 description = ""; | |
333 } | |
334 | |
335 try { | |
336 place = placemark.getElementsByTagName("address")[0].childNodes[0].nodeValue; | |
337 } | |
338 catch(e){ | |
339 place = ""; | |
340 } | |
341 | |
342 var getDate = function(timeData){ | |
343 var date; | |
344 if (timeData.length == 6) { | |
345 g = time.SECOND; | |
346 date = new Date(Date.UTC(timeData[0], timeData[1]-1, timeData[2], timeData[3], timeData[4], timeData[5])); | |
347 } | |
348 else if (timeData.length == 3) { | |
349 g = time.DAY; | |
350 date = new Date(Date.UTC(timeData[0], timeData[1]-1, timeData[2])); | |
351 } | |
352 else if (timeData.length == 2) { | |
353 g = time.MONTH; | |
354 date = new Date(Date.UTC(timeData[0], timeData[1]-1, 1)); | |
355 } | |
356 else if (timeData.length == 1) { | |
357 g = time.YEAR; | |
358 date = new Date(Date.UTC(timeData[0], 0, 1)); | |
359 } | |
360 if (granularity < g) { | |
361 granularity = g; | |
362 } | |
363 if( timeData[0] && timeData[0] < 100 ){ | |
364 date.setFullYear(timeData[0]); | |
365 } | |
366 return date; | |
367 } | |
368 | |
369 try { | |
370 timeData = getTimeData( placemark.getElementsByTagName("TimeStamp")[0].getElementsByTagName("when")[0].childNodes[0].nodeValue ); | |
371 if( timeData != null ){ | |
372 timeStamp = getDate(timeData); | |
373 } | |
374 if( timeStamp == undefined ){ | |
375 continue; | |
376 } | |
377 } | |
378 catch(e){ | |
379 try { | |
380 timeStamp = undefined; | |
381 var timeSpanTag = placemark.getElementsByTagName("TimeSpan")[0]; | |
382 var timeDataStart = getTimeData( timeSpanTag.getElementsByTagName("begin")[0].childNodes[0].nodeValue ); | |
383 var startTime = getDate(timeDataStart); | |
384 var timeDataEnd = getTimeData( timeSpanTag.getElementsByTagName("end")[0].childNodes[0].nodeValue ); | |
385 var endTime = getDate(timeDataEnd); | |
386 timeSpan = { start: startTime, end: endTime }; | |
387 } | |
388 catch(e){ | |
389 continue; | |
390 } | |
391 } | |
392 | |
393 try { | |
394 coordinates = placemark.getElementsByTagName("Point")[0].getElementsByTagName("coordinates")[0].childNodes[0].nodeValue; | |
395 var lonlat = coordinates.split(","); | |
396 if( lonlat[0] == "" || lonlat[1] == "" || isNaN(lonlat[0]) || isNaN(lonlat[1]) ){ | |
397 continue; | |
398 } | |
399 newObjects.push(new DataObject(name, description, place, timeStamp, timeSpan, g, lonlat[0], lonlat[1])); | |
400 } | |
401 catch(e){ | |
402 continue; | |
403 } | |
404 | |
405 } | |
406 var dataset = new DataSet( newObjects, term, granularity ); | |
407 dataset.source = ds; | |
408 var core = this; | |
409 var status = document.getElementById("statusText"); | |
410 status.innerHTML = "Space & Time Aggregation ..."; | |
411 setTimeout( function(){ | |
412 core.addDataSet( dataset ); | |
413 core.unblockUI(); | |
414 }, | |
415 1 ); | |
416 }, | |
417 | |
418 /** | |
419 * parses the kml-file which includes the results for a given search request | |
420 * @param {File} kmlFile | |
421 * @param {String} term the term identifier for the resulting dataset | |
422 */ | |
423 parseKml: function(kmlFile,term,ds){ | |
424 var core = this; | |
425 if( this.blocked ){ | |
426 setTimeout( function(){ core.parseKml(kmlFile,term,ds); }, 100 ); | |
427 return; | |
428 } | |
429 core.blockUI(); | |
430 $.ajax({ | |
431 url: kmlFile, | |
432 dataType: "xml", | |
433 beforeSend: function(){ | |
434 var status = document.getElementById("statusText"); | |
435 status.innerHTML = "Retrieving Data ..."; | |
436 }, | |
437 success: function(xml){ | |
438 var status = document.getElementById("statusText"); | |
439 status.innerHTML = "Parsing Data ..."; | |
440 setTimeout( function(){ core.parseIt(xml,term,ds); }, 1 ); | |
441 } | |
442 }); | |
443 }, | |
444 | |
445 /** | |
446 * updates the timeplot and table element. | |
447 * its called from the STIMap object, when objects on the map had been selected by featureSelect or polygon. | |
448 * @param {boolean} hover true, if there was a hover selection | |
449 */ | |
450 updateTimeAndTable: function(hover){ | |
451 updateTables(hover); | |
452 this.timeplot.polesBySlices(); | |
453 this.refining = -1; | |
454 }, | |
455 | |
456 /** | |
457 * updates the map, timeplot and table element. | |
458 * its called from the STITable object, when a text selection has been done | |
459 */ | |
460 updateMapAndTimeAndTable: function(index){ | |
461 updateTables(hover); | |
462 this.timeplot.polesBySlices(); | |
463 this.map.updateMap(); | |
464 this.refining = index; | |
465 }, | |
466 | |
467 /** | |
468 * updates the timeplot and map element. | |
469 * its called from the STITable object, when objects in one of the tables had been selected. | |
470 */ | |
471 updateTimeAndMap: function(){ | |
472 this.map.updateMap(); | |
473 this.timeplot.polesBySlices(); | |
474 this.refining = -1; | |
475 }, | |
476 | |
477 /** | |
478 * updates the table and map element. | |
479 * its called from the STITimeplot object, when objects in the timeplot had been selected by timestamp or -range. | |
480 * @param {boolean} hover true, if there was a hover selection | |
481 */ | |
482 updateTableAndMap: function(hover){ | |
483 updateTables(hover); | |
484 this.map.updateMap(); | |
485 this.refining = -1; | |
486 }, | |
487 | |
488 /** | |
489 * initializes the sti components (map, timeplot, table) depending on the top masks of the data sets. | |
490 * its called after a new search was performed, refining or undo button had been clicked | |
491 */ | |
492 initElements: function(){ | |
493 this.reset(); | |
494 var dataSets = this.history[this.historyIndex].dataSets; | |
495 var granularity = 0; | |
496 for( var i=0; i<dataSets.length; i++ ){ | |
497 if( dataSets[i].maxGranularity > granularity ){ | |
498 granularity = dataSets[i].maxGranularity; | |
499 } | |
500 } | |
501 this.timeplot.initTimeplot(dataSets, granularity); | |
502 this.map.initObjectLayer(dataSets); | |
503 initTables(); | |
504 }, | |
505 | |
506 /** | |
507 * deletes a data set with specific index | |
508 * @param {int} index the index of the data set to delete | |
509 */ | |
510 deleteDataSet: function(index){ | |
511 var color = colors[index]; | |
512 colors.splice(index, 1); | |
513 var oldDataSets = this.history[this.historyIndex].dataSets; | |
514 var newDataSets = []; | |
515 for( var i=0; i<oldDataSets.length; i++ ){ | |
516 if( i != index ){ | |
517 newDataSets.push( oldDataSets[i] ); | |
518 } | |
519 } | |
520 colors.splice( newDataSets.length, 0, color ); | |
521 this.addHistoryEntry(new HistoryEntry(newDataSets)); | |
522 this.initElements(); | |
523 this.reset(); | |
524 }, | |
525 | |
526 /** | |
527 * Switches to another history entry with the given index | |
528 * @param {int} index the index of the history entry to load | |
529 */ | |
530 switchThroughHistory: function( index ){ | |
531 this.historyIndex = index; | |
532 this.initElements(); | |
533 }, | |
534 | |
535 /** | |
536 * Adds a new history entry containing actual datasets | |
537 * @param {HistoryEntry} historyEntry the history entry to add | |
538 */ | |
539 addHistoryEntry: function( historyEntry ){ | |
540 this.history = this.history.slice(0,this.historyIndex+1); | |
541 this.history.push(historyEntry); | |
542 this.historyIndex = this.history.length - 1; | |
543 addHistoryItem(this.historyIndex); | |
544 }, | |
545 | |
546 /** | |
547 * adds an element to the user individual data set | |
548 * @param {DataObject} object the data object to add | |
549 */ | |
550 addElement: function(object){ | |
551 if (this.individualDataSet == null) { | |
552 this.individualDataSet = new DataSet([], "individual", 0); | |
553 var oldDataSets = this.history[this.historyIndex].dataSets; | |
554 var newDataSets = oldDataSets.concat(this.individualDataSet); | |
555 this.addHistoryEntry(new HistoryEntry(newDataSets)); | |
556 } | |
557 this.individualDataSet.addObject(object); | |
558 this.initElements(); | |
559 this.reset(); | |
560 }, | |
561 | |
562 /** | |
563 * resets the core within all elements and data objects to non-selection-status | |
564 */ | |
565 reset: function(){ | |
566 this.refining = -2; | |
567 var dataSets = this.history[this.historyIndex].dataSets; | |
568 for (var i = 0; i < dataSets.length; i++){ | |
569 for (var j = 0; j < dataSets[i].objects.length; j++){ | |
570 dataSets[i].objects[j].setPercentage(0); | |
571 dataSets[i].objects[j].setHover(false); | |
572 } | |
573 } | |
574 this.timeplot.resetTimeplot(); | |
575 this.map.resetMap(); | |
576 updateTables(false); | |
577 }, | |
578 | |
579 /** | |
580 * Security hover unselection of elements if browser events got stucked | |
581 */ | |
582 undoHover: function(update){ | |
583 | |
584 this.map.hoverUnselect(); | |
585 this.timeplot.hoverUnselect(update); | |
586 }, | |
587 | |
588 createLink: function(){ | |
589 var c = this.map.openlayersMap.getCenter(); | |
590 var map = this.map.openlayersMap.baseLayer.id; | |
591 var mapCenter = { lon: c.lon, lat: c.lat }; | |
592 var mapZoom = this.map.openlayersMap.getZoom(); | |
593 var data = []; | |
594 // store complete history in data --> flow of history events | |
595 // 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) | |
596 // flag for the ability to display stored history or not | |
597 }, | |
598 | |
599 lockScreen: function(){ | |
600 this.lockScreenContainer.style.visibility = "visible"; | |
601 this.lockScreenContainer.style.height = getDocHeight()+"px"; | |
602 }, | |
603 | |
604 lockScreenMessage: function(div){ | |
605 this.lockScreenContainer.innerHTML = ""; | |
606 var lockScreenDiv = document.createElement("div"); | |
607 lockScreenDiv.setAttribute('class','lockScreen'); | |
608 this.lockScreenContainer.appendChild(lockScreenDiv); | |
609 this.lockScreenContainer.appendChild(div); | |
610 }, | |
611 | |
612 unlockScreen: function(){ | |
613 this.lockScreenContainer.style.visibility = "hidden"; | |
614 } | |
615 | |
616 }; | |
617 | |
618 /** | |
619 * defines a history entry | |
620 * @param {DataSet[]} dataSets the datasets of this history entry | |
621 * | |
622 * @constructor | |
623 */ | |
624 function HistoryEntry( dataSets ){ | |
625 this.dataSets = dataSets; | |
626 }; |