397 lines
15 KiB
JavaScript
397 lines
15 KiB
JavaScript
/**********************************************************************
|
|
* events.js *
|
|
* script for event specific functions and setup *
|
|
**********************************************************************/
|
|
|
|
/* License
|
|
Copyright 2014 Kasper D. Fischer <kasper.fischer@rub.de>
|
|
|
|
This program is free software: you can redistribute it and/or modify it
|
|
under the terms of the GNU General Public License as published by the Free
|
|
Software Foundation, either version 3 of the License, or (at your option)
|
|
any later version.
|
|
|
|
This program is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
with this program. If not, see http://www.gnu.org/licenses/.
|
|
|
|
$Id$
|
|
*/
|
|
|
|
/* do reverse geolocation lookup */
|
|
function getGeolocation(id, lat, lng) {
|
|
if ( !geolocationTable[id] ) {
|
|
$.getJSON( config['ajax']['nominatimURL'], { lat: lat, lon: lng, zoom: 10, format: "json" } )
|
|
.done(function( json ) {
|
|
var city = json.address["city"];
|
|
var country = json.address["country"];
|
|
var countryCode = json.address["country_code"].toUpperCase();
|
|
geolocationTable[id] = city;
|
|
( country != "Deutschland" ) ? geolocationTable[id] = geolocationTable[id] + " ("+countryCode+")" : null;
|
|
if ( city ) {
|
|
$("#eventstable a.toggle[eventid="+id+"]").text(geolocationTable[id]);
|
|
var sort = [[0,1],[1,1],[2,1]];
|
|
$("#eventstable").trigger("update", [true]);
|
|
$("#eventstable").trigger("updateCache");
|
|
$("#eventstable").trigger("sorton", [sort]);
|
|
} else {
|
|
console.log("Nominatim did not provide a city tag for "+lat+" / "+lng);
|
|
};
|
|
})
|
|
.fail(function( jqxhr, textStatus, error ) {
|
|
var err = textStatus + ", " + error;
|
|
console.log( "Request Failed: " + err );
|
|
});
|
|
};
|
|
};
|
|
|
|
/* Load events using ajax */
|
|
function ajaxLoadEvents(stime, etime) {
|
|
var mapBounds = map.getBounds();
|
|
var N = mapBounds.getNorth();
|
|
var E = mapBounds.getEast();
|
|
var S = mapBounds.getSouth();
|
|
var W = mapBounds.getWest();
|
|
if ( !stime ) {
|
|
var stime = new Date();
|
|
stime.setDate(stime.getDate()-config['map']['timespan']);
|
|
};
|
|
if ( !etime ) {
|
|
var etime = new Date();
|
|
etime.setDate(etime.getDate()+1);
|
|
};
|
|
var request_data = {
|
|
starttime: sprintf("%d-%02d-%02d", stime.getFullYear(), stime.getMonth()+1, stime.getDate()),
|
|
endtime: sprintf("%d-%02d-%02d", etime.getFullYear(), etime.getMonth()+1, etime.getDate()),
|
|
minlat: S-config['map']['latlngDelta'],
|
|
maxlat: N+config['map']['latlngDelta'],
|
|
minlon: W-config['map']['latlngDelta'],
|
|
maxlon: E+config['map']['latlngDelta'],
|
|
minmag: config['event']['minMag']-config['event']['minMagDelta'],
|
|
};
|
|
$.ajax({
|
|
type: "GET",
|
|
url: config['ajax']['eventURL'],
|
|
data: request_data,
|
|
dataType: "xml",
|
|
success: function (xml) {
|
|
$(xml).find('event').each(function () {
|
|
var id = $(this).attr('publicID').split('/')[2];
|
|
var mag = $(this).find('magnitude > mag > value').text();
|
|
var otime = $(this).find('origin > time > value').text();
|
|
var lng = $(this).find('origin > longitude > value').text();
|
|
var lat = $(this).find('origin > latitude > value').text();
|
|
var evaluationMode = $(this).find('evaluationMode').text();
|
|
var evaluationStatus = $(this).find('evaluationStatus').text();
|
|
var type = $(this).find('type').last().text();
|
|
var location
|
|
// try use location with reverse geolocation lookup (nominatim), check cache first
|
|
// use getLocation if it fails or description -> text if it also fails
|
|
if ( geolocationTable[id] ) {
|
|
location = geolocationTable[id];
|
|
} else {
|
|
location = getGeolocation(id, lat, lng);
|
|
( location ) ? null : location = $(this).find('description > text').text();
|
|
};
|
|
// create table row: Date, Time, Mag, Location
|
|
if ( !eventTable[id] && $.inArray(type, config['event']['typeWhitelist'] )+1 && $.inArray(evaluationStatus, config['event']['evaluationBlacklist'])<0 && Number(mag)+0.05 >= config['event']['minMag'] ) {
|
|
var row = '<tr class="tablesorter-hasChildRow">'
|
|
+ '<td class="utctime-date">'+otime.split('.')[0]+'Z</td>'
|
|
+ '<td class="utctime-time">'+otime.split('.')[0]+'Z</td>'
|
|
+ sprintf('<td class="ar">%.1f</td>', Number(mag))
|
|
+ '<td><a href="#" class="toggle" eventid="'+id+'">'+location+'</a><a class="map-link" href="#" eventid="'+id+'">Karte</a></td>'
|
|
+ '</tr>';
|
|
row += '<tr class="tablesorter-childRow">'
|
|
+ '<td colspan="4" eventid="'+id+'">Daten werden geladen ...</td></tr>';
|
|
var added = $('#eventstable tbody').append(row);
|
|
added.find('.tablesorter-childRow td').hide();
|
|
$('#eventstable').find('td.utctime-date').each(function() {
|
|
$.localtime.formatObject($(this), "dd.MM.yyyy");
|
|
$(this).removeClass('utctime-date');
|
|
$(this).addClass('localtime-date');
|
|
});
|
|
$('#eventstable').find('td.utctime-time').each(function() {
|
|
$.localtime.formatObject($(this), "HH:mm");
|
|
$(this).removeClass('utctime-time');
|
|
$(this).addClass('localtime-time');
|
|
});
|
|
// create marker
|
|
var marker = addEventMarker(id, Number(lat), Number(lng), Number(mag));
|
|
var text = sprintf('<h3 eventid="%s">%s</h3>', id, location)
|
|
+ sprintf('<p>Ereignis: %s</br>', id)
|
|
+ sprintf('Ort: %.4f °N, %.4f °O </br>', Number(lat), Number(lng))
|
|
+ sprintf('Zeit: <span class="utctime">%sZ</span></p>', otime.split('.')[0], otime.split('.')[0]);
|
|
marker.bindPopup(text);
|
|
};
|
|
});
|
|
},
|
|
complete: function () {
|
|
initStationTable();
|
|
var sort = [[0,1],[1,1],[2,1]];
|
|
$("#eventstable").trigger("update", [true]);
|
|
$("#eventstable").trigger("updateCache");
|
|
$("#eventstable").trigger("sorton", [sort]);
|
|
initMapLink();
|
|
},
|
|
error: function( jqxhr, textStatus, error ) {
|
|
var err = textStatus + ", " + error;
|
|
console.log( "Request Failed: " + err );
|
|
}
|
|
});
|
|
};
|
|
|
|
/* ajaxLoadEventInfo */
|
|
function ajaxLoadEventInfo(id) {
|
|
var request_data = {
|
|
eventid: id,
|
|
includeArrivals: true,
|
|
};
|
|
$.ajax({
|
|
type: "GET",
|
|
url: config['ajax']['eventURL'],
|
|
data: request_data,
|
|
dataType: "xml",
|
|
success: function (xml) {
|
|
eventDetails[id] = true;
|
|
$(xml).find('event').each(function () {
|
|
var mag = $(this).find('magnitude > mag > value').text();
|
|
var otime = $(this).find('origin > time > value').text();
|
|
var lng = $(this).find('origin > longitude > value').text();
|
|
var lng_err = $(this).find('origin > longitude > uncertainty').text();
|
|
var lat = $(this).find('origin > latitude > value').text();
|
|
var lat_err = $(this).find('origin > latitude > uncertainty').text();
|
|
var depth = $(this).find('origin > depth > value').text();
|
|
var depth_err = $(this).find('origin > depth > uncertainty').text();
|
|
var rms = $(this).find('origin > quality > standardError').text();
|
|
var gap = $(this).find('origin > quality > azimuthalGap').text();
|
|
var phases_count = $(this).find('origin > quality > usedPhaseCount').text();
|
|
var type = $(this).find('type').last().text();
|
|
var row = "<pre>"
|
|
+ sprintf("ID %32s\n", id)
|
|
+ sprintf("Type %30s\n\n", type)
|
|
+ "Origin\n"
|
|
+ sprintf("Magnitude %13.1f\n", Number(mag))
|
|
+ sprintf("Date %18s\n", otime.split('T')[0])
|
|
+ sprintf("Time %18s UTC\n", otime.split('T')[1].substring(0, 11))
|
|
+ sprintf("Latitude %14.4f °N +- %4.1f km\n",Number(lat), Number(lat_err))
|
|
+ sprintf("Longitude %13.4f °E +- %4.1f km\n", Number(lng), Number(lng_err))
|
|
+ sprintf("Depth %14.1f km +- %4.1f km\n", Number(depth)/1000., Number(depth_err)/1000.)
|
|
+ sprintf("Residual RMS %7.1f sec\n", Number(rms))
|
|
+ sprintf("Azimuthal gap %6.1f °\n\n", Number(gap))
|
|
+ sprintf("%d Phase arrivals:\n", Number(phases_count))
|
|
+ "sta net dist azi phase time res wt sta\n";
|
|
row = row + '</pre>';
|
|
$('#eventstable > tbody > tr.tablesorter-childRow > td[eventid='+id+']').html(row);
|
|
});
|
|
},
|
|
complete: function () {
|
|
console.log('Fetched details for event '+id);
|
|
},
|
|
error: function( jqxhr, textStatus, error ) {
|
|
var err = textStatus + ", " + error;
|
|
console.log( "Request Failed: " + err );
|
|
}
|
|
});
|
|
};
|
|
|
|
/* add row to table
|
|
obsolete */
|
|
function addEventRow(id, props) {
|
|
$('#eventstable').tablesorter({
|
|
sortList: "[[0,0], [1,1]], [2,1]",
|
|
resort: true,
|
|
showProcessing: true,
|
|
pager_size: 35
|
|
});
|
|
var html = '<tr class="tablesorter-hasChildRow">'
|
|
+ '<td class="utctime-date">'+props.date+'T'+props.time.split('.')[0]+'Z</td>'
|
|
+ '<td class="utctime-time">'+props.date+'T'+props.time.split('.')[0]+'Z</td>'
|
|
+ '<td class="ar">'+props.mag+'</td>'
|
|
+ '<td><a href="#" class="toggle">'+props.location+'</a><a class="map-link" href="#" eventid="'+id+'">Karte</a></td>'
|
|
+ '</tr>'
|
|
+ '<tr class="tablesorter-childRow">'
|
|
+ '<td colspan="4" eventid="'+id+'">'
|
|
+ "<pre>ID "+id+"\n\n"
|
|
+ "Origin\n"
|
|
+ "Date "+props.date+"\n"
|
|
+ "Time "+props.time+"\n"
|
|
+ "Latitude "+props.lat+" deg +/- "+props.lat_err+" km\n"
|
|
+ "Longitude "+props.lon+" deg +/- "+props.lon_err+" km\n"
|
|
+ "Depth "+props.depth+" km +/- "+props.depth_err+" km\n"
|
|
+ "Residual RMS "+props.rms+" s\n"
|
|
+ "Azimuthal gap "+props.gap+" deg\n\n"
|
|
+ props.no_phases + " Phase arrivals:\n"
|
|
+ "sta net dist azi phase time res wt sta\n";
|
|
for ( i = 0 ; i < props.no_phases ; i++ ) {
|
|
html += props.phases[i];
|
|
( i < props.no_phases -1 ) ? html += "\n" : null ;
|
|
};
|
|
html += "</pre></td></tr>\n";
|
|
var added = $('#eventstable tbody').append(html);
|
|
added.find('.tablesorter-childRow td').hide();
|
|
$('#eventstable').find('td.utctime-date').each(function() {
|
|
$.localtime.formatObject($(this), "dd. MM. yyyy");
|
|
$(this).removeClass('utctime-date');
|
|
$(this).addClass('localtime-date');
|
|
});
|
|
$('#eventstable').find('td.utctime-time').each(function() {
|
|
$.localtime.formatObject($(this), "HH:mm");
|
|
$(this).removeClass('utctime-time');
|
|
$(this).addClass('localtime-time');
|
|
});
|
|
// force resorting
|
|
$("#eventstable").trigger("update", [true]);
|
|
};
|
|
|
|
/* toggles visibility of filtered markers
|
|
* only events in the event list are shown */
|
|
function toggleFilteredMarkers() {
|
|
// show all shown events in map
|
|
$("#eventstable > tbody > tr:not(.filtered) > td > a.map-link").each( function() {
|
|
if ( $(this).attr("eventid") ) {
|
|
eventTable[$(this).attr("eventid")].setStyle({opacity: 1, strokeOpacity: 1, fillOpacity: config['event']['markerOpacity']});
|
|
};
|
|
});
|
|
|
|
// hide filtered events in map
|
|
$("#eventstable > tbody > tr.filtered > td > a.map-link").each( function() {
|
|
if ( $(this).attr("eventid") ) {
|
|
eventTable[$(this).attr("eventid")].setStyle({opacity: 0, strokeOpacity: 0, fillOpacity: 0});
|
|
};
|
|
});
|
|
highlightFirstEvent();
|
|
};
|
|
|
|
/* Highlight the first event of the event list on the map if no
|
|
* other event is selected */
|
|
function highlightFirstEvent() {
|
|
var highlightStyle = {
|
|
color: 'red',
|
|
fillColor: '#f03',
|
|
};
|
|
var normalStyle = {
|
|
fillColor: "#FFF500",
|
|
color: "#FFF500"
|
|
};
|
|
$("#eventstable a.map-link").each( function() {
|
|
if ( $(this).attr("eventid") ) {
|
|
eventTable[$(this).attr("eventid")].setStyle(normalStyle);
|
|
$(this).removeClass('first');
|
|
$(this).text('Karte');
|
|
};
|
|
});
|
|
$("#eventstable > tbody > tr:not(.filtered)").first().find("a.map-link").each(function() {
|
|
if ( $(this).attr("eventid") ) {
|
|
eventTable[$(this).attr("eventid")].setStyle(highlightStyle);
|
|
$(this).addClass('first');
|
|
$(this).text('Karte (rot)');
|
|
};
|
|
});
|
|
};
|
|
|
|
function highlightEvent( id ) {
|
|
var highlightStyle = {
|
|
color: 'red',
|
|
fillColor: '#f03',
|
|
};
|
|
var normalStyle = {
|
|
fillColor: "#FFF500",
|
|
color: "#FFF500"
|
|
};
|
|
$("#eventstable > tbody > tr:not(.filtered)").find("a.map-link").each( function() {
|
|
if ( $(this).attr("eventid") ) {
|
|
if ( $(this).attr("eventid") == id ) {
|
|
eventTable[$(this).attr("eventid")].setStyle(highlightStyle);
|
|
$(this).addClass('first');
|
|
$(this).text('Karte (rot)');
|
|
} else {
|
|
eventTable[$(this).attr("eventid")].setStyle(normalStyle);
|
|
$(this).removeClass('first');
|
|
$(this).text('Karte');
|
|
}
|
|
};
|
|
});
|
|
};
|
|
|
|
/**********************************************************************
|
|
* document ready *
|
|
**********************************************************************/
|
|
$(document).ready(function() {
|
|
// tablesorter for event list
|
|
$("#eventstable").tablesorter(
|
|
{
|
|
theme : 'blue',
|
|
dateFormat : "ddmmyyyy",
|
|
headers: {
|
|
0: { sorter: "shortDate" }
|
|
},
|
|
cssChildRow: "tablesorter-childRow", // this is the default setting
|
|
widgets: ["uitheme", "zebra", "filter", "pager"], // initialize zebra and filter widgets, "scroller"
|
|
widgetOptions: {
|
|
// possible variables: {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows}
|
|
pager_output: '# {startRow} - {endRow} ({totalRows}) | Seite {page} ({totalPages})',
|
|
pager_removeRows: false,
|
|
pager_size: 35,
|
|
filter_childRows : true,
|
|
filter_cssFilter : 'tablesorter-filter',
|
|
filter_startsWith : false,
|
|
filter_ignoreCase : true,
|
|
scroller_height: $('div.map').height() - 250,
|
|
scroller_barWidth: 10,
|
|
scroller_jumpToHeader: false,
|
|
sortList: "[[0,1], [1,1], [2,1]]",
|
|
resort: true,
|
|
showProcessing: true,
|
|
}
|
|
});
|
|
|
|
// hide child rows
|
|
$('#eventstable > tbody > tr.tablesorter-childRow td').hide();
|
|
|
|
// update map after filtering
|
|
$('#eventstable').bind('filterEnd', function(){
|
|
toggleFilteredMarkers();
|
|
});
|
|
|
|
// highlight first event
|
|
$('#eventstable').bind('sortEnd', function(){
|
|
highlightFirstEvent();
|
|
});
|
|
|
|
// show / hide event info
|
|
$('#eventstable').delegate('.toggle', 'click' , function(){
|
|
// load event details
|
|
var eventid = $(this).attr('eventid');
|
|
( eventDetails[eventid] ) ? null : ajaxLoadEventInfo(eventid);
|
|
|
|
// toggle visibility of selected row
|
|
$(this).closest('tr').nextUntil('tr.tablesorter-hasChildRow').find('td').toggle('slow');
|
|
|
|
// mark currently selected row and remove class selected from all other rows
|
|
// hide other rows
|
|
$(this).closest('tr').nextUntil('tr.tablesorter-hasChildRow').find('td').addClass('selected-now');
|
|
$(this).closest('tbody').find('td.selected').each(function(){
|
|
if ( ! $(this).hasClass('selected-now') ) {
|
|
$(this).hide();
|
|
$(this).removeClass('selected');
|
|
};
|
|
});
|
|
$(this).closest('tr').nextUntil('tr.tablesorter-hasChildRow').find('td').each(function(){
|
|
$(this).removeClass('selected-now');
|
|
var selected = $(this).hasClass('selected');
|
|
if ( selected ) {
|
|
$(this).removeClass('selected');
|
|
} else {
|
|
$(this).addClass('selected');
|
|
};
|
|
});
|
|
|
|
return false;
|
|
});
|
|
|
|
});
|