Compare commits

...

No commits in common. "main" and "release/r20131023" have entirely different histories.

46 changed files with 898 additions and 3776 deletions

35
.gitattributes vendored
View File

@ -1,33 +1,4 @@
* text=auto !eol
scripts/mkEvents.csh -text
wsgi/showEnv.py -text
www/.htaccess -text
www/copyright.inc.de -text
www/external/TileLayer.Grayscale.js -text
www/external/css/dvf.css -text
www/external/css/leaflet.label.css -text
www/external/easyPrint.css -text
www/external/first.png -text
www/external/jQuery.print.js -text
www/external/jquery.localtime-0.9.1.min.js -text
www/external/jquery.tablesorter.min.js -text
www/external/jquery.tablesorter.pager.css -text
www/external/jquery.tablesorter.pager.min.js -text
www/external/jquery.tablesorter.widgets.min.js -text
www/external/last.png -text
www/external/leaflet-dvf.markers.min.js -text
www/external/leaflet.css -text
www/external/leaflet.easyPrint.js -text
www/external/leaflet.js -text
www/external/leaflet.label.js -text
www/external/next.png -text
www/external/prev.png -text
www/external/print.png -text
www/external/sprintf.min.js -text
www/external/theme.blue.css -text
www/external/widget-pager.js -text
www/impressum.inc.de -text
www/info.inc.de -text
www/logo_RUB_155x30.png -text
www/more.inc.de -text
www/spinner.gif -text
/mapkey.js -text
/mapkey_yearly.js -text
/quakes2kml.py -text

57
.gitignore vendored
View File

@ -1,56 +1 @@
## Visual Studio Code
# Visual Studio Code files
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
## MacOS / OSX
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
## Vagrant
.vagrant/
# Log files (if you are creating logs in debug mode, uncomment this)
# *.log
## Project Files
wsgi/.idea
www/dlsv
www/stations.xml
www/index.html
www/data/events.xml
www/data/geolocation.js
scripts/*.json
scripts/*.xml
/*.kml

View File

@ -1,13 +0,0 @@
# Version: v1.3 (2023-04-17)
FROM nginx:alpine
# set labels
LABEL org.opencontainers.image.authors="kasper.fischer@rub.de"
# copy nginx config files
COPY nginx/nginx.conf /etc/nginx/nginx.conf
COPY nginx/mime.types /etc/nginx/mime.types
COPY nginx/default.conf /etc/nginx/conf.d/default.conf
# copy webpage content
COPY www /usr/share/nginx/html/map

16
Vagrantfile vendored
View File

@ -1,16 +0,0 @@
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/jammy64"
config.vm.synced_folder ".", "/vagrant"
config.vm.network(:forwarded_port, guest: 80, host: 8888)
config.vm.provision :shell, inline: <<-SHELL
sudo apt-get -y update
sudo apt-get -y install nginx
echo "Starting nginx..."
sudo ln -s /vagrant/www /var/www/html/map
sudo cp /vagrant/www/index.html.en /vagrant/www/index.html
sudo useradd -s /bin/false nginx
sudo service nginx restart
SHELL
end

View File

@ -1,19 +0,0 @@
version: "3.9"
networks:
seisobs:
external: false
services:
map:
build:
context: .
dockerfile: Dockerfile
image: seisobs-map:v1.1
networks:
- seisobs
volumes:
- ./www/data:/usr/share/nginx/html/map/data:ro
ports:
- "${SEISOBS_MAPPORT}:80"
restart: unless-stopped

92
index.html Normal file
View File

@ -0,0 +1,92 @@
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<!-- $Id$ -->
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>RUB SeisObs - Station and Seismicity Map</title>
<style type="text/css">
html, body, #map {
margin: 0;
width: 100%;
height: 100%;
z-index: 10000;
}
#maptext {
position: absolute;
bottom: 1em;
left: 1em;
width: 20%;
z-index: 15000;
background-color: white;
padding: 0 0.5em 0.5em 0.5em;
}
#mapkey {
position: absolute;
top: 18px;
left: 80px;
width: 420px;
height: 80px;
z-index: 20000;
background: rgb(255, 255, 255);
background: rgba(255, 255, 255, 0.7);
padding: 0px 0px 0px 0px;
}
</style>
</head>
<body>
<style type="text/css">
.olControlAttribution {
position: absolute;
font-size: 10px;
text-align: left;
color: #eeeeee;
bottom: 0;
left: 0;
right:auto !important;
background: #130085; /* fallback for IE - IE6 requires background shorthand*/
background: rgba(0, 60, 136, 0.3);
filter: alpha(opacity=30);
font-family: 'Lucida Grande', Verdana, Geneva, Lucida, Arial, Helvetica, sans-serif;
border-radius: 5px 0 0 0;
}
.olControlAttribution a {
color: #eeeeee;
font-weight: bold;
}
</style>
<script type='text/javascript' src='OpenLayers.js'></script>
<script type='text/javascript' src='https://maps.google.com/maps/api/js?sensor=false&amp;v=3'></script>
<script type='text/javascript' src='station_map_www.js'></script>
<script type='text/javascript' src='mapkey.js'></script>
<script type='text/javascript' src='lang/de.js'></script>
<script type='text/javascript'>
OpenLayers.Util.extend(OpenLayers.Lang.de, {
'Overlays' : 'Ebenen',
'Stations' : 'Stationen',
'Events': 'Ereignisse',
'Grid': 'Gitter',
'Google Maps (Terrain)': 'Google Maps (Gelände)',
'Google Maps (Satellite)': 'Google Maps (Satellit)',
'Google Maps (Streets)': 'Google Maps (Straßen)',
'Year': 'Jahr',
'Magnitudes': 'Magnituden',
'Magnitude': 'Magnitude',
'stations': 'Stationen',
'Zoom in to resolve individual stations.': 'Zum Anzeigen der einzelnen Stationen vergrößern.'
});
OpenLayers.Lang.setCode(document.documentElement.lang);
</script>
<div id="map">
<script type='text/javascript'>init(true, true, true, false);</script>
</div>
<div id="mapkey">
<script type='text/javascript'>initKey(true, false, false);</script>
</div>
<!-- <div id="maptext">
<h3 id="title">Stations</h3>
</div> -->
</body>
</html>

87
mapkey.js Normal file
View File

@ -0,0 +1,87 @@
/*
* JavaScript code to generate maps used by the
* Seismological Observatory of the Ruhr-University Bochum
*
* Copyright 2012 Kasper D. Fischer <kasper.fischer@rub.de>
*
* License
*
* 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: station_map.js 321 2012-02-13 14:52:11Z kasper $
*/
/* Global variables */
var mapkey;
/* Main function to create the map */
function initKey(showMag, showAge, showStation) {
/* Creating map */
wgs84 = new OpenLayers.Projection("EPSG:4326");
mapkey = new OpenLayers.Map(
'mapkey',
{
projection: wgs84,
displayProjection: wgs84,
controls: []
}
);
// Show Magnitudes
mag_layer = new OpenLayers.Layer.Vector(
'Magnitude Scale',
{
projection: wgs84,
isBaseLayer: true
}
);
// Adding custom style for Magnitudes
var mag_style_default = new OpenLayers.Style({
fillColor: '#ff0000', fillOpacity: 0.2,
strokeColor: '#ff0000', strokeWidth: 2,
pointRadius: "${pntsize}",
label: "${text}", labelXOffset: "${offset}",
graphicName: 'circle'
});
var mag_style_map = new OpenLayers.StyleMap({
'default': mag_style_default
});
mag_layer.styleMap = mag_style_map;
// Adding points as map key, size: mag*3.5+2.0
var pointt = new OpenLayers.Geometry.Point(-10, 0);
var mag_pointt = new OpenLayers.Feature.Vector(pointt, {pntsize: 0, text: 'Magnitude', offset: 2});
var point0 = new OpenLayers.Geometry.Point(0, 0);
var mag_point0 = new OpenLayers.Feature.Vector(point0, {pntsize: 0.5*3.5+2.0, text: '0.5', offset: 17});
var point1 = new OpenLayers.Geometry.Point(10, 0);
var mag_point1 = new OpenLayers.Feature.Vector(point1, {pntsize: 1.5*3.5+2.0, text: '1.5', offset: 20.5});
var point2 = new OpenLayers.Geometry.Point(20, 0);
var mag_point2 = new OpenLayers.Feature.Vector(point2, {pntsize: 2.5*3.5+2.0, text: '2.5', offset: 24.0});
var point3 = new OpenLayers.Geometry.Point(30, 0);
var mag_point3 = new OpenLayers.Feature.Vector(point3, {pntsize: 3.5*3.5+2.0, text: '3.5', offset: 27.5});
mag_layer.addFeatures([mag_pointt, mag_point0, mag_point1, mag_point2, mag_point3]);
mapkey.addLayer(mag_layer);
mag_layer.setVisibility(true);
// Set initial view
if (!mapkey.getCenter()) {
mapkey.setCenter(0,0);
mapkey.zoomToExtent(mag_layer.getDataExtent());
}
}

1
mapkey_yearly.js Symbolic link
View File

@ -0,0 +1 @@
mapkey.js

View File

@ -1,76 +0,0 @@
# Version: v1.3 (2023-04-17)
server {
listen 80;
listen [::]:80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
set $first_language $http_accept_language;
if ($http_accept_language ~* '^(.+?),') {
set $first_language $1;
}
set $language_suffix 'en';
if ($first_language ~* 'de') {
set $language_suffix 'de';
}
#rewrite rules to /map/
rewrite ^(.*)/index(\.html)*$ /map/index.html.$language_suffix last;
rewrite ^/favicon.ico$ /map/favicon.ico last;
rewrite ^/map$ /map/ last;
rewrite ^/map.js$ /map/map.js last;
rewrite ^/karte$ /map/ last;
rewrite ^/karte/$ /map/ last;
rewrite ^/karte/(.*)$ /map/$1 last;
if ($uri !~ "^/map") {
rewrite ^(.*)/(.*)$ /map$1/$2 last;
}
#location /map {
# root /usr/share/nginx/html/;
# index index.html.$language_suffix index.html;
# #try_files $uri.$language_suffix $uri.html.$language_suffix $uri.html $uri index.html.$language_suffix index.html;
#}
location / {
root /usr/share/nginx/html/;
index index.html.$language_suffix index.html;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}

View File

@ -1,98 +0,0 @@
types {
text/html html htm shtml de en;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
application/javascript js;
application/atom+xml atom;
application/rss+xml rss;
text/mathml mml;
text/plain txt;
text/vnd.sun.j2me.app-descriptor jad;
text/vnd.wap.wml wml;
text/x-component htc;
image/png png;
image/svg+xml svg svgz;
image/tiff tif tiff;
image/vnd.wap.wbmp wbmp;
image/webp webp;
image/x-icon ico;
image/x-jng jng;
image/x-ms-bmp bmp;
font/woff woff;
font/woff2 woff2;
application/java-archive jar war ear;
application/json json;
application/mac-binhex40 hqx;
application/msword doc;
application/pdf pdf;
application/postscript ps eps ai;
application/rtf rtf;
application/vnd.apple.mpegurl m3u8;
application/vnd.google-earth.kml+xml kml;
application/vnd.google-earth.kmz kmz;
application/vnd.ms-excel xls;
application/vnd.ms-fontobject eot;
application/vnd.ms-powerpoint ppt;
application/vnd.oasis.opendocument.graphics odg;
application/vnd.oasis.opendocument.presentation odp;
application/vnd.oasis.opendocument.spreadsheet ods;
application/vnd.oasis.opendocument.text odt;
application/vnd.openxmlformats-officedocument.presentationml.presentation
pptx;
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
xlsx;
application/vnd.openxmlformats-officedocument.wordprocessingml.document
docx;
application/vnd.wap.wmlc wmlc;
application/wasm wasm;
application/x-7z-compressed 7z;
application/x-cocoa cco;
application/x-java-archive-diff jardiff;
application/x-java-jnlp-file jnlp;
application/x-makeself run;
application/x-perl pl pm;
application/x-pilot prc pdb;
application/x-rar-compressed rar;
application/x-redhat-package-manager rpm;
application/x-sea sea;
application/x-shockwave-flash swf;
application/x-stuffit sit;
application/x-tcl tcl tk;
application/x-x509-ca-cert der pem crt;
application/x-xpinstall xpi;
application/xhtml+xml xhtml;
application/xspf+xml xspf;
application/zip zip;
application/octet-stream bin exe dll;
application/octet-stream deb;
application/octet-stream dmg;
application/octet-stream iso img;
application/octet-stream msi msp msm;
audio/midi mid midi kar;
audio/mpeg mp3;
audio/ogg ogg;
audio/x-m4a m4a;
audio/x-realaudio ra;
video/3gpp 3gpp 3gp;
video/mp2t ts;
video/mp4 mp4;
video/mpeg mpeg mpg;
video/quicktime mov;
video/webm webm;
video/x-flv flv;
video/x-m4v m4v;
video/x-mng mng;
video/x-ms-asf asx asf;
video/x-ms-wmv wmv;
video/x-msvideo avi;
}

View File

@ -1,32 +0,0 @@
# Version: v1.3 (2023-04-17)
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}

90
print.html Normal file
View File

@ -0,0 +1,90 @@
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<!-- $Id$ -->
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>RUB SeisObs - Station and Seismicity Map</title>
<style type="text/css">
html, body, #map {
margin: 0;
width: 1440px;
height: 900px;
z-index: 10000;
}
#maptext {
position: absolute;
bottom: 1em;
left: 1em;
width: 20%;
z-index: 15000;
background-color: white;
padding: 0 0.5em 0.5em 0.5em;
}
#mapkey {
position: absolute;
top: 18px;
left: 80px;
width: 320px;
height: 34px;
z-index: 20000;
background: rgb(255, 255, 255);
background: rgba(255, 255, 255, 0.7);
padding: 0px 0px 0px 0px;
}
</style>
</head>
<body>
<style type="text/css">
.olControlAttribution {
position: absolute;
font-size: 10px;
text-align: left;
color: #eeeeee;
bottom: 0;
left: 0;
right:auto !important;
background: #130085; /* fallback for IE - IE6 requires background shorthand*/
background: rgba(0, 60, 136, 0.3);
filter: alpha(opacity=30);
font-family: 'Lucida Grande', Verdana, Geneva, Lucida, Arial, Helvetica, sans-serif;
border-radius: 5px 0 0 0;
}
.olControlAttribution a {
color: #eeeeee;
font-weight: bold;
}
</style>
<script type='text/javascript' src='OpenLayers.js'></script>
<script type='text/javascript' src='https://maps.google.com/maps/api/js?sensor=false&amp;v=3'></script>
<script type='text/javascript' src='station_map_www.js'></script>
<script type='text/javascript' src='mapkey.js'></script>
<script type='text/javascript' src='lang/de.js'></script>
<script type='text/javascript'>
OpenLayers.Util.extend(OpenLayers.Lang.de, {
'Overlays' : 'Ebenen',
'Stations' : 'Stationen',
'Events': 'Ereignisse',
'Grid': 'Gitter',
'Google Maps (Terrain)': 'Google Maps (Gelände)',
'Google Maps (Satellite)': 'Google Maps (Satellit)',
'Google Maps (Streets)': 'Google Maps (Straßen)',
'Magnitudes': 'Magnituden',
'stations': 'Stationen',
'Zoom in to resolve individual stations.': 'Zum Anzeigen der einzelnen Stationen vergrößern.'
});
OpenLayers.Lang.setCode(document.documentElement.lang);
</script>
<div id="map">
<script type='text/javascript'>init(true, true, true, true);</script>
</div>
<div id="mapkey">
<script type='text/javascript'>initKey(true, false, false);</script>
</div>
<!-- <div id="maptext">
<h3 id="title">Stations</h3>
</div> -->
</body>
</html>

95
quakes2kml.py Executable file
View File

@ -0,0 +1,95 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
"""
Creates KML file with station info.
License
Copyright 2012 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: stations.py 311 2012-01-31 14:34:31Z kasper $
"""
import csv, os, shutil, sys
import simplekml
from obspy.core import UTCDateTime
# create new empty KML file
kml = simplekml.Kml()
# create empyt folder to contain styles and stations
quakes_folder = kml.newfolder(name="Earthquakes")
# style of broad-band stations
quake1m_style = simplekml.Style()
quake1m_style.iconstyle.color = 'ff0000ff'
quake1m_style.iconstyle.icon.href = 'circle'
# style of short periode stations
quake1y_style = simplekml.Style()
quake1y_style.iconstyle.color = 'ffff00ff'
# style of short periode stations
quakeAll_style = simplekml.Style()
quakeAll_style.iconstyle.color = 'ff00ffff'
# reading earthquake list
events = []
num_header = 0
with open('quakes.txt', 'rb') as f:
reader = csv.reader(f, delimiter='\t')
try:
for row in reader:
if ( reader.line_num <= num_header ):
header = row
else:
events.append(row)
except csv.Error, e:
sys.exit('file {0}, line {1}: {2}'.format('quakes.txt', reader.line_num, e))
# adding station markers
for event in events:
eventTime = UTCDateTime(event[0]+' '+event[1])
nowTime = UTCDateTime()
lat = event[2]
lon = event[3]
mag = event[4]
region = event[5]
pnt = quakes_folder.newpoint(
name = region,
coords = [(lon, lat)],
description = "<p>Magnitude {0}<br>Time {1}<br>Location {2}N {3}E</p>".format(
mag, eventTime.strftime('%Y-%m-%d %H:%M:%S'), lat, lon)
)
pnt.extendeddata.newdata('mag', mag)
pnt.extendeddata.newdata('lat', lat)
pnt.extendeddata.newdata('lon', lon)
pnt.extendeddata.newdata('time', eventTime.strftime('%Y-%m-%d %H:%M:%S'))
pnt.extendeddata.newdata('age', nowTime-eventTime)
pnt.extendeddata.newdata('pntsize', float(mag)*3.5+2)
if (( nowTime - eventTime ) > 60*60*24*30 ):
pnt.extendeddata.newdata('pntcolor', '#ffa500')
pnt.style = quake1y_style
elif (( nowTime - eventTime ) > 60*60*24*365 ):
pnt.extendeddata.newdata('pntcolor', '#ffff00')
pnt.style = quakeAll_style
else:
pnt.extendeddata.newdata('pntcolor', '#ff0000')
pnt.style = quake1m_style
# saving the KML file
kml.save('quakes.kml')

View File

@ -1,15 +0,0 @@
#!/bin/bash
# Version: v1.3 (2023-04-17)
# get starting date
# find gdate or date command ( OSX: brew install coreutils)
# the date command on OSX is not compatible to the linux date command
datecmd=$((which gdate || which date )| grep bin)
STIME="${1:-$(${datecmd} -d 6-month-ago +%Y-%m-%d)}"
STIME="${STIME:-$(date +%Y-%m-%d)}"
# get output filename
OUTPUT="${2:--}"
# fetch events
curl -s -o ${OUTPUT} "https://fdsnws.geophysik.ruhr-uni-bochum.de/fdsnws/event/1/query?starttime=${STIME}&minlat=50.0&maxlat=53.0&minlon=4.0&maxlon=10.0&minmag=0.7"

View File

@ -1,157 +0,0 @@
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
'''
Script to lookup city names of events with Nominatim service
The input should be an valid quakeML file passed to stdin.
The output will will be a javascript structure to be included in the
SeisObs map service.
The script should be updated regularly keep the total number of all
AJAX calls to the Nominatim service small, e. g. :
curl -s "https://fdsnws.geophysik.ruhr-uni-bochum.de/fdsnws/event/1/query?minlat=50&maxlat=54&minlon=3&maxlon=10&minmag=1" | mkGeolocationTable.py > geolocationTable.js
Version: v1.3 (2023-04-17)
License
Copyright 2020-2021 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/.
'''
def mkGeolocationTable(file=''):
## imports
# XML ElementTree
try:
import xml.etree.cElementTree as ET
except ImportError:
import xml.etree.ElementTree as ET
# json
import json as JSON
# sys stdin
from sys import stdin
# geopy
from geopy.geocoders import Photon
from geopy.extra.rate_limiter import RateLimiter
from geopy.exc import GeocoderServiceError
## constants
URL = 'https://photon.komoot.io/reverse?lon={lng:.3f}&lat={lat:.3f}&limit=10'
NAMESPACES = {'sc3': 'http://geofon.gfz-potsdam.de/ns/seiscomp3-schema/0.7',
'qml': 'http://quakeml.org/xmlns/bed/1.2'}
# try loading the file
geolocationTable = {}
if file :
try:
jsonfile = open(file)
jsonfileContent = jsonfile.read().split('=')[1].replace(';', '')
geolocationTable = JSON.loads(jsonfileContent)
except:
geolocationTable = {}
logging.warning('Could not parse file %s' %file)
# parse event.xml
DOM = ET.parse(stdin).getroot()
geolocator = Photon()
reverse_geolocate = RateLimiter(geolocator.reverse, min_delay_seconds=2)
# iterate over all events
count = 0
for event in DOM.iterfind('qml:eventParameters/qml:event', NAMESPACES):
count += 1
publicID = event.attrib['publicID'].split('/')[2]
lat = float(event.find('./qml:origin/qml:latitude/qml:value', NAMESPACES).text)
lng = float(event.find('./qml:origin/qml:longitude/qml:value', NAMESPACES).text)
evaluationMode = event.find('./qml:origin/qml:evaluationMode', NAMESPACES).text
if publicID in geolocationTable:
logging.warning('Skipping cached event {id}'.format(id=publicID))
elif evaluationMode == 'automatic':
logging.warning('Skipping automatic event {id}'.format(id=publicID))
else:
logging.info('Processing event {id}'.format(id=publicID))
try:
locations = reverse_geolocate("{lat:.3f}, {lng:.3f}".format(lat=lat, lng=lng),exactly_one=False,limit=10)
except GeocoderServiceError:
logging.warning('Reverse Geolocation failed. Skipping event.')
continue
place = []
for location in locations:
try:
place = location.raw['properties']['city']
except KeyError:
try:
place = location.raw['properties']['town']
except KeyError:
try:
place = location.raw['properties']['village']
except KeyError:
try:
place = location.raw['properties']['county']
except KeyError:
logging.debug('Could not extract city for event {id} at {lat:.3f} N / {lng:.3f} E (Service: {url}), trying next returned result'
.format(id=publicID, lat=lat, lng=lng, url=URL.format(lat=lat,lng=lng)))
logging.debug(location.raw)
if not place:
logging.critical('Could not extract city for event {id} at {lat:.3f} N / {lng:.3f} E (Service: {url})'
.format(id=publicID, lat=lat, lng=lng, url=URL.format(lat=lat,lng=lng)))
geolocationTable[publicID] = place
# dump json
print('var geolocationTable = {0};'.format(JSON.dumps(geolocationTable, sort_keys=True)))
logging.info("processed %d events", count)
# __main__
if __name__ == "__main__":
# use module logging
import logging
# parse arguments
import argparse
versionText = 'v1.3 (2023-04-17)'
parser = argparse.ArgumentParser(
description='Reverse geocoding lookup of events in xml format (stdin).',
epilog=versionText)
parser.add_argument('-V', '--version', action='version', version=versionText,
help="show version")
parser.add_argument('-f', '--file', action='store', dest='file',
help='read in JSON file containing old output.')
group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true",
help="increase output verbosity")
group.add_argument("-q", "--quiet", action="store_true",
help="disable output")
group.add_argument("-d", "--debug", action="store_true",
help="show debugging output",
)
cla = parser.parse_args()
# set logging level
if cla.quiet:
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.ERROR)
elif cla.verbose:
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
elif cla.debug:
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG)
else:
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.WARN)
# call mkGeolocationTable(...)
mkGeolocationTable(file=cla.file)

View File

@ -1,21 +0,0 @@
#!/bin/bash
# version: v1.3 (2023-04-17)
function fail {
printf '%s\n' "$1" >&2 ## Send message to stderr.
exit "${2-1}" ## Return a code specified by $2, or 1 by default.
}
if [ $# -le 1 ] ; then
echo usage: ${0} version_string files ...
exit 0
fi
version="$1"
shift
files="$*"
echo ${version} ${files}
which sponge > /dev/null || fail "sponge util must be installed"
for file in ${files}; do
sed "s/V\{5\}/${version}"/ ${file} | sponge ${file}
done

455
station_map_www.js Normal file
View File

@ -0,0 +1,455 @@
/*
* JavaScript code to generate maps used by the
* Seismological Observatory of the Ruhr-University Bochum
*
* Copyright 2013 Kasper D. Fischer <kasper.fischer@rub.de>
*
* License
*
* 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$
*/
/* Global variables */
var map, mapargs;
/* Main function to create the map */
function init(showGoogle, showStations, showQuakes, noFrils) {
/* get parameters from url */
mapargs = OpenLayers.Util.getParameters();
if (mapargs['print']) {
if (mapargs['print'] == 'true') {
noFrils = true;
} else {
noFrils = false;
}
}
if (mapargs['quakes']) {
if (mapargs['quakes'] == 'true') {
showQuakes = true;
} else {
showQuakes = false;
}
}
if (mapargs['stations']) {
if (mapargs['stations'] == 'true') {
showStations = true;
} else {
showStations = false;
}
}
/* Creating map */
if ( !noFrils ) {
map = new OpenLayers.Map(
'map',
{
projection: new OpenLayers.Projection('EPSG:900913'),
displayProjection: new OpenLayers.Projection('EPSG:4326'),
controls: [
new OpenLayers.Control.Attribution(),
new OpenLayers.Control.KeyboardDefaults(),
new OpenLayers.Control.LayerSwitcher({}),
new OpenLayers.Control.MousePosition(),
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.OverviewMap(),
new OpenLayers.Control.PanZoomBar({zoomWorldIcon: true}),
new OpenLayers.Control.Permalink({anchor: noFrils}),
new OpenLayers.Control.ScaleLine({geodesic: true})
]
}
);
} else {
map = new OpenLayers.Map(
'map',
{
projection: new OpenLayers.Projection('EPSG:900913'),
displayProjection: new OpenLayers.Projection('EPSG:4326'),
controls: [
new OpenLayers.Control.Attribution(),
new OpenLayers.Control.KeyboardDefaults(),
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.Permalink({anchor: noFrils}),
new OpenLayers.Control.ScaleLine({geodesic: true})
]
}
);
};
/* Base Layers */
// OpenStreetMap
var osmde_map_layer = new OpenLayers.Layer.OSM(
'OpenStreetMap (DE)',
[
"http://a.tile.openstreetmap.de/tiles/osmde/${z}/${x}/${y}.png",
"http://b.tile.openstreetmap.de/tiles/osmde/${z}/${x}/${y}.png",
"http://c.tile.openstreetmap.de/tiles/osmde/${z}/${x}/${y}.png"
],
{
attribution: 'Kartenbasis: Daten von <a href="http://www.openstreetmap.org/">OpenStreetMap</a> - Veröffentlicht unter <a href="http://opendatacommons.org/licenses/odbl/">ODbL</a><br />' +
'Seismische Daten von <a href="http://www.gmg.ruhr-uni-bochum.de/geophysik/seisobs">Ruhr-Universität Bochum</a> - Veröffentlicht unter <a href="http://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>'
}
);
var osm_map_layer = new OpenLayers.Layer.OSM('OpenStreetMap (Standard)');
map.addLayers([
osm_map_layer,
osmde_map_layer
]);
// Google Maps
if (showGoogle) {
var googleT_map_layer = new OpenLayers.Layer.Google(
OpenLayers.i18n('Google Maps (Terrain)'),
{type: google.maps.MapTypeId.TERRAIN,transitionEffect: "resize"}
);
var googleS_map_layer = new OpenLayers.Layer.Google(
OpenLayers.i18n("Google Maps (Satellite)"),
{type: google.maps.MapTypeId.SATELLITE, numZoomLevels: 22,transitionEffect: "resize"}
);
var googleH_map_layer = new OpenLayers.Layer.Google(
'Google Maps (Hybrid)',
{type: google.maps.MapTypeId.HYBRID, numZoomLevels: 20,transitionEffect: "resize"}
);
var googleM_map_layer = new OpenLayers.Layer.Google(
OpenLayers.i18n("Google Maps (Streets)"),
{numZoomLevels: 20,transitionEffect: "resize"}
);
map.addLayers([
googleT_map_layer,
googleS_map_layer,
googleH_map_layer,
googleM_map_layer
]);
};
// OpenMapQuest
var omq_map_layer = new OpenLayers.Layer.OSM(
'OpenMapQuest',
[
"http://otile1.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.jpg",
"http://otile2.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.jpg",
"http://otile3.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.jpg",
"http://otile4.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.jpg"
],
{
attribution: 'Kartenbasis: Daten von <a href="http://www.openstreetmap.org/">OpenStreetMap</a> - Veröffentlicht unter <a href="http://opendatacommons.org/licenses/odbl/">ODbL</a><br />' +
'Seismische Daten von <a href="http://www.gmg.ruhr-uni-bochum.de/geophysik/seisobs">Ruhr-Universität Bochum</a> - Veröffentlicht unter <a href="http://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>'
}
);
map.addLayers([omq_map_layer]);
// ESRI
/* var esri_map_layer = new OpenLayers.Layer.XYZ(
'ESRI',
"https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/${z}/${y}/${x}",
{
sphericalMercator: true,
attribution: 'Copyright &copy; 2013 by ESRI. ' +
'This work is licensed under the Web Services and API <a href="http://links.esri.com/agol_tou" target="_blank">Terms of Use</a>.'
}
);
map.addLayers([esri_map_layer]); */
// Show quakes
quakes_layer = loadKML(OpenLayers.i18n("Events"), 'quakes.kml', false, true);
quakes_layer.events.on({'loadend': setQuakesMapkeyVisibility});
quakes_layer.events.on({'visibilitychanged': setQuakesMapkeyVisibility});
map.addLayer(quakes_layer);
quakes_layer.setVisibility(showQuakes);
// color coding of events
var day2sec = 86400.;
var timeNow = new Date().getTime()/1000.;
var timeCoding;
if (mapargs['timeCoding']) {
switch ( mapargs['timeCoding'] ){
case 'decade':
timeCoding = {
'colors': [ '#0000ff', '#ff0000', '#ffa500', '#ffff00'],
'times': [1262300400, 946681200, 631148400, 315529200]
// 1.1.2010, 1.1.2000, 1.1.1990, 1.1.1980
};
};
};
if (!mapargs['timeCoding'] || !timeCoding ) {
timeCoding = {
'colors': ['#0000ff', '#ff0000', '#ffa500', '#ffff00'],
'ages': [7*day2sec, 30.4375*day2sec, 182.625*day2sec, 365.25*day2sec]
};
};
// Adding custom style to quakes
var quake_style_default = new OpenLayers.Style({
fillColor: '${pntcolor}', fillOpacity: 0.2,
strokeColor: '${pntcolor}', strokeWidth: 2,
pointRadius: '${pntsize}'
},
{
context: {
pntcolor: function(feature){
try {
return feature.data.pntcolor.value;
} catch (e) {
return "#E020F0"
}
},
/* if (timeCoding['ages']) {
quakeAge = feature.data.age.value;
// quakeAge = timeNow - feature.data.stime.value;
for ( level = 0; level < timeCoding['ages'].length; level += 1 ) {
if ( quakeAge <= timeCoding['ages'][level] ) {
return timeCoding['colors'][level];
};
};
} else if (timeCoding['decade']) {
return feature.data.pntcolor.value;
} else {
quakeTime = timeNow + feature.data.age.value;
// quakeTime = feature.data.stime.value;
for ( level = 0; level < timeCoding['times'].length; level += 1 ) {
if ( quakeTime >= timeCoding['times'][level] ) {
return timeCoding['colors'][level];
};
};
};
//return '#ffffff00';
}, */
pntsize: function(feature){
try {
// quakeAge = feature.data.age.value;
// quakeAge = timeNow - feature.data.time.value;
// if ( timeCoding['ages'] && quakeAge > timeCoding['ages'][timeCoding['ages'].length-1] ) {
// return 0;
// } else {
return feature.data.pntsize.value;
//}
} catch (e) {
return 6;
}
}
}
});
var quake_style_select = quake_style_default.clone();
quake_style_select.defaultStyle.fillOpacity = 0.8;
var quake_style_map = new OpenLayers.StyleMap({
'default': quake_style_default,
'select': quake_style_select
});
quakes_layer.styleMap = quake_style_map;
// Show stations
stations_layer = loadKML(OpenLayers.i18n("Stations"), 'stations.kml', false, noFrils);
map.addLayer(stations_layer);
stations_layer.setVisibility(showStations);
// Adding custom style to stations
var station_style_default = new OpenLayers.Style({
fillColor: '${pointColor}', fillOpacity: 0.8, // #8dae10
strokeColor: 'black', strokeWidth: 2,
label: "${text}", labelXOffset: 15, labelAlign: 'l',
fontColor: "${tcolor}", fontFamily: 'sans-serif', fontWeight: 'bold',
pointRadius: '${pntsize}',
graphicName: '${pntsymbol}'
},
{
context: {
pointColor: function(feature){
if (feature.attributes.count) {
return '#8dae10';
} else {
return '#8dae10'; //return feature.data.pntcolor.value;
}
},
text: function(feature){
if (feature.attributes.count) {
var c = feature.attributes.count;
for (var i=0; i<feature.cluster.length; i++){
c = c + feature.cluster[i].data.extrastation.value * 1.0;
}
return c + ' ' + OpenLayers.i18n('stations');
} else {
return feature.data.name;
}
},
tcolor: function(feature){
if (feature.attributes.count) {
return 'black';
} else {
return feature.data.tcolor.value;
}
},
pntsize: function(feature){
if (feature.attributes.count) {
return Math.min(feature.attributes.count * 2.0 + 6.0, 12);
} else {
return feature.data.pntsize.value;
}
},
pntsymbol: function(feature){
if (feature.attributes.count) {
return 'circle';
} else {
return 'triangle';
}
}
}
});
var station_style_select = station_style_default.clone();
station_style_select.defaultStyle.strokeWidth = 4;
var station_style_map = new OpenLayers.StyleMap({
'default': station_style_default,
'select': station_style_select
});
stations_layer.styleMap = station_style_map;
// Set initial view
if (!map.getCenter()) {
map.setCenter(new OpenLayers.LonLat(7.5, 51.8).transform('EPSG:4326','EPSG:900913'), 9);
}
// Enable animated zoom
for (var i=map.layers.length-1; i>=0; --i) {
map.layers[i].animationEnabled = true;
}
// Show description
select = new OpenLayers.Control.SelectFeature([quakes_layer, stations_layer]);
map.addControl(select);
select.activate();
// Add graticule
map.addControl(new OpenLayers.Control.Graticule({layerName: OpenLayers.i18n("Grid"), visible: false}));
}
/* Function to load KML file */
function loadKML(name, file, useStyle, noFrils) {
// define layer strategy
var layer_strategy
if (noFrils){
layer_strategy = [
new OpenLayers.Strategy.Fixed(),
];
} else {
// define cluster parameters
var thresholdValue = 4;
if (map.getZoom() <= 8){ thresholdValue = 2}
if (map.getZoom() >= 10){ thresholdValue = 6}
if (noFrils) {
thresholdValue = 99;
distanceValue = 0
};
var distanceValue = 10;
if (map.getZoom() <= 9){ distanceValue = 20}
layer_strategy = [
new OpenLayers.Strategy.Fixed(),
new OpenLayers.Strategy.Cluster({distance: distanceValue, threshold: thresholdValue})
];
}
// create kml layer
var kml_layer = new OpenLayers.Layer.Vector(
name,
{
strategies: layer_strategy,
protocol: new OpenLayers.Protocol.HTTP(
{
url: file,
format: new OpenLayers.Format.KML({
extractStyles: useStyle,
extractAttributes: true,
maxDepth: 1
})
}),
transitionEffect: "resize",
projection: new OpenLayers.Projection("EPSG:4326")
});
kml_layer.events.on(
{
"featureselected": onFeatureSelect,
"featureunselected": onFeatureUnselect
});
// return layer object
return kml_layer;
}
/* Function called at closing of a popup */
function onPopupClose(evt) {
select.unselectAll();
}
/* Function called when clicking on a marker */
function onFeatureSelect(event) {
var feature = event.feature;
// Since KML is user-generated, do naive protection against
// Javascript.
if (feature.attributes.name){
var content = "<h3>"+feature.attributes.name + "</h3><p>" + feature.attributes.description + '</p>';
if (content.search("<script") != -1) {
content = "Content contained Javascript! Escaped content below.<br>" + content.replace(/</g, "&lt;");
}
} else {
var content = '<h3>';
for (var i=0; i<feature.cluster.length; i++){
content = content + feature.cluster[i].attributes.name;
if (i < feature.cluster.length-1) {
content = content + ', ';
}
}
content += '</h3>'+
OpenLayers.i18n('Zoom in to resolve individual stations.');
}
var popup = new OpenLayers.Popup.FramedCloud(
"popups",
feature.geometry.getBounds().getCenterLonLat(),
new OpenLayers.Size(100,100),
content,
null, true,
onPopupClose
);
feature.popup = popup;
map.addPopup(popup);
}
/* Function to close popups */
function onFeatureUnselect(event) {
var feature = event.feature;
if(feature.popup) {
map.removePopup(feature.popup);
feature.popup.destroy();
delete feature.popup;
}
}
/* Function to activate map legend */
function setQuakesMapkeyVisibility() {
var mapkey_div = document.getElementById('mapkey');
var quakes_visibility = quakes_layer.getVisibility();
if (quakes_visibility) {
mapkey_div.style.display = "block";
mapkey_div.style.visibility = "visible";
} else {
if (mapkey_div) {
mapkey_div.style.visibility = "hidden";
mapkey_div.style.display = "none";
}
}
}

74
stations2kml.py Executable file
View File

@ -0,0 +1,74 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
"""
Creates KML file with station info.
License
Copyright 2012 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$
"""
import simplekml
# create new empty KML file
kml = simplekml.Kml()
# create empyt folder to contain styles and stations
stationsFolder = kml.newfolder(name="Stations")
# station types
stationTypes = {
'broadband': {'textColor': '#003560', 'pointSize': 10, 'pointColor': '#ff0000'},
'shortperiod': {'textColor': '#003560', 'pointSize': 10, 'pointColor': '#ffa500'},
'auxiliary': {'textColor': '#003560', 'pointSize': 8, 'pointColor': '#ffff00'},
'geothermie': {'textColor': '#003560', 'pointSize': 10, 'pointColor': '#ffff00'}
}
# setting station info
stations = {
'BUG, BKLB': [( 7.2693, 51.4406), 'broadband', 1, "GRSN station BUG, STS-2 seismometer<br />RuhrNet station BKLB, GS-13 seismometer"],
'BULI': [( 7.2602, 51.4544), 'auxiliary', 0, 'RuhrNet station BULI, Mark L4c-3D seismometer'],
'BTEZ': [( 7.2790, 51.4490), 'auxiliary', 0, 'RuhrNet station BTEZ, GS-13 seismometer'],
'BPFI': [( 7.2276, 51.4185), 'auxiliary', 0, 'RuhrNet station BBFI, Mark L4c-3D seismometer'],
'HMES': [( 7.7263, 51.6578), 'broadband', 0, 'RuhrNet station HMES, Trillium 40 seismometer'],
'BRHE': [( 6.5710, 51.5155), 'shortperiod', 0, 'RuhrNet station BRHE, Mark L4c-3D seismometer'],
'ZERL': [( 6.8695, 51.6207), 'shortperiod', 0, 'RuhrNet station ZERL, Mark L4c-3D seismometer'],
'ZER1': [( 6.8252, 51.5947), 'auxiliary', 0, 'RuhrNet station ZER1, Mark L4c-3D seismometer'],
'ZER2': [( 6.9060, 51.5871), 'auxiliary', 0, 'RuhrNet station ZER2, Mark L4c-3D seismometer'],
'ZER3': [( 6.8384, 51.6128), 'auxiliary', 0, 'RuhrNet station ZER3, Mark L4c-3D seismometer'],
'BAVN': [( 7.1220, 51.7380), 'broadband', 0, 'RuhrNet station BAVN, STS-2 seismometer'],
'BAVS': [( 7.1331, 51.7000), 'auxiliary', 0, 'RuhrNet station BAVS, Mark L4c-3D seismometer'],
'IBBN': [( 7.7566, 52.3072), 'broadband', 0, 'GEOFON station IBBN, STS-2 seismometer'],
'IBBE': [( 7.7943, 52.2998), 'auxiliary', 0, 'RuhrNet station IBBE, Mark L4c-3D seismometer'],
'IBBS': [( 7.7486, 52.2843), 'auxiliary', 0, 'RuhrNet station IBBS, Mark L4c-3D seismometer'],
'KERA': [(23.5577, 35.3692), 'broadband', 0, 'GEOFON station KERA, STS-2 seismometer'],
'KARP': [(27.1612, 35.5472), 'broadband', 0, 'GEOFON station KARP, STS-2 seismometer']
}
# adding station markers
for key, value in stations.iteritems():
pnt = stationsFolder.newpoint(
name = key,
coords = [(value[0][0], value[0][1])],
description = value[3]
)
pnt.extendeddata.newdata('pntsize', stationTypes[value[1]]['pointSize'])
pnt.extendeddata.newdata('pntcolor', stationTypes[value[1]]['pointColor'])
pnt.extendeddata.newdata('tcolor', stationTypes[value[1]]['textColor'])
pnt.extendeddata.newdata('extrastation', value[2])
# saving the KML file
kml.save('stations.kml')

View File

@ -1,405 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Get waveform data from FDSN web service and create a fancy plot
This programme runs as a script or as a WSGI application.
:version v1.1 (2021-10-31)
:license
Copyright 2020 Kasper Fischer <kasper.fischer@ruhr-uni-bochum.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 2 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, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
"""
def utc2local(utctime, timezone='Europe/Berlin'):
"""
utc2local(utctime, timezone='Europe/Berlin')
converts the UTCDateTime object utctime into a
datetime object of the given timezone
"""
import pytz
utc = pytz.utc
local = pytz.timezone(timezone)
utctime = utc.localize(utctime.datetime)
return local.normalize(utctime.astimezone(local))
def fancy_plot(st, wsgi=False, img_format='png', color=True):
"""
creating fancy plot from ObsPy stream st
returns cStringIO object if wsgi == True
:type st: ObsPy Stream object
:type wsgi: bool
:type img_format: str
:type color: bool
"""
import matplotlib as mpl
from matplotlib.dates import date2num, AutoDateLocator, AutoDateFormatter
if wsgi:
try:
import cStringIO as StringIO
except ImportError:
import StringIO as StringIO
import matplotlib.pyplot as plt
from numpy import arange
# setup figure parameters
if wsgi:
mpl.rcParams['figure.figsize'] = [12.0, 6.75] # 16:9 aspect ratio
else:
mpl.rcParams['figure.figsize'] = [16.0, 9.0] # 16:9 aspect ratio
# get starttime, endtime, localtime and timezone
tr = st[0]
stime = tr.stats.starttime
etime = tr.stats.endtime
localtime = utc2local(stime)
if localtime.tzname() == u'CET':
tzname = u'MEZ'
else:
tzname = u'MESZ'
tz = localtime.timetz().tzinfo
# create proper time vector
d = arange(date2num(stime), date2num(etime), (date2num(etime) - date2num(stime)) / tr.stats.npts)
# setup time axis decorator
locator = AutoDateLocator(interval_multiples=True, minticks=5, maxticks=8, tz=tz)
minor_locator = AutoDateLocator(interval_multiples=True, minticks=9, maxticks=70, tz=tz)
formatter = AutoDateFormatter(locator, tz=tz)
formatter.scaled[1. / (24. * 60.)] = '%H:%M:%S'
formatter.scaled[1. / (24. * 60. * 60. * 10.)] = '%H:%M:%S.%f'
# draw figure
if color:
trace_color = {'Z': 'r', 'N': 'b', 'E': 'g'}
else:
trace_color = {'Z': 'k', 'N': 'k', 'E': 'k'}
fig = plt.figure()
ax1 = fig.add_subplot(311)
ax1.xaxis.set_major_locator(locator)
ax1.xaxis.set_major_formatter(formatter)
ax1.plot_date(d, st.select(component='Z')[0].data * 1000., trace_color['Z'], label=u'Z', tz=tz)
plt.title(u'Station %s' % st[0].stats.station, fontsize=24)
plt.legend(loc='upper right')
ax1.grid(b=True)
ax2 = fig.add_subplot(312, sharex=ax1, sharey=ax1)
ax2.plot_date(d, st.select(component='N')[0].data * 1000., trace_color['N'], label=u'N', tz=tz)
ax2.grid(b=True)
plt.ylabel(u'Geschwindigkeit [mm/s]', fontsize=16)
plt.legend(loc='upper right')
ax3 = fig.add_subplot(313, sharex=ax1, sharey=ax1)
ax3.plot_date(d, st.select(component='E')[0].data * 1000., trace_color['E'], label=u'E', tz=tz)
ax3.grid(b=True)
plt.legend(loc='upper right')
plt.xlabel(u'%s (%s)' % (localtime.strftime('%d.%m.%Y'), tzname), fontsize=16)
ax1.minorticks_on()
ax1.xaxis.set_minor_locator(minor_locator)
if wsgi:
buf = StringIO.StringIO()
plt.savefig(buf, format=img_format, facecolor="lightgray")
return buf
else:
if cla['filename']:
plt.savefig(cla['filename'], dpi=300, transparent=True)
else:
plt.show()
def trace_dayplot(st, deltat = None,
ftype='none', fmin=1.0, fmax=7.0,
col=('b', 'r', 'g'), interval=20, outpattern='',
wsgi=False):
"""
:type st: object
:type ftype: str
:type fmin: float
:type fmax: float
:type col: tuple
:type interval: float
:type outpattern: str
:type wsgi: bool
"""
if wsgi:
try:
import cStringIO as StringIO
except ImportError:
import StringIO as StringIO
# filter
if (ftype == 'bandpass') or (ftype == 'bandstop'):
st.filter(ftype, freqmin=fmin, freqmax=fmax)
elif (ftype == 'lowpass') or (ftype == 'highpass'):
st.filter(ftype, freq=fmin)
st.merge()
stime = st[0].stats.starttime
if deltat:
etime = stime + deltat
else:
etime = st[0].stats.endtime
# plot
for i in range(0, len(st)):
if wsgi:
buf = StringIO.StringIO()
st[i].plot(outfile=buf, format=outpattern, type='dayplot', color=col, interval=interval,
starttime=stime, endtime=etime)
return buf
else:
if outpattern != '':
imagefile = outpattern.format(st[i].stats.network,
st[i].stats.station,
st[i].stats.channel,
st[i].stats.starttime.year,
st[i].stats.starttime.julday)
st[i].plot(type='dayplot', color=col, interval=interval,
outfile=imagefile)
else:
st[i].plot(type='dayplot', color=col, interval=interval)
def get_fdsn(bulk_request, output='VEL', base_url='https://ariadne.geophysik.ruhr-uni-bochum.de'):
"""
Fetches waveform data from FDSN web service and returns
instrument corrected seismogram of type given in parameter output.
Acceptable values for output are "VEL", "DISP" and "ACC" (see ObsPy documentation)
:rtype : object
:param bulk_request: list
:param output: str
:param base_url: str
:return: ObsPy Stream() object
"""
import warnings
from obspy.fdsn import Client
from obspy.fdsn.header import FDSNException
try:
with warnings.catch_warnings():
warnings.simplefilter("ignore")
client = Client(base_url=base_url, debug=False)
st = client.get_waveforms_bulk(bulk_request, attach_response=True)
st.merge()
stime = st[0].stats.starttime
etime = st[0].stats.endtime
for trace in st.traces:
stime = max(stime, trace.stats.starttime)
etime = min(etime, trace.stats.endtime)
st.trim(starttime=stime, endtime=etime)
# choose 1 s taper
taper_fraction = 1 / (etime - stime)
for trace in st.traces:
# filter, remove response
trace.filter('bandpass', freqmin=0.01, freqmax=25, corners=3, zerophase=False). \
remove_response(output=output, zero_mean=True, taper=True, taper_fraction=taper_fraction)
return st
except FDSNException:
return None
def main(backend=None, args=None, wsgi=False):
"""
Main function to create a waveform plot.
This functions calls get_fdsn and fancy_plot to create the figure.
If wsgi == True it returns an ioString object containing the figure.
:type backend: str
:type args: dict
:type wsgi: bool
:rtype : object
:param backend:
:param args:
:param wsgi:
:return: ioString object with created image
"""
import warnings
import matplotlib as mpl
if wsgi:
backend = 'Agg'
if backend:
with warnings.catch_warnings():
warnings.simplefilter("ignore")
mpl.use(backend)
from obspy import UTCDateTime
if args:
deltat = args['length']
if args['stime']:
otime = UTCDateTime(args['stime'])
else:
otime = UTCDateTime() - 3600. - deltat
network = args['station'].split('.')[0]
station = args['station'].split('.')[1]
if args['type'] == 'dayplot':
if network == 'Z3':
channel = 'HHZ'
else:
channel = 'BHZ'
else:
if args['length'] < 3600.:
channel = 'HH?'
else:
if network == 'Z3':
channel = 'HH?'
else:
channel = 'BH?'
else:
otime = UTCDateTime() - 3600.
deltat = 30
network = 'GR'
station = 'BUG'
channel = 'HH?'
st = get_fdsn([(network, station, '*', channel, otime, otime + deltat)], base_url=args['server'])
if st is not None:
stime = max(st[0].stats.starttime, otime)
etime = min(st[0].stats.endtime, otime + deltat)
st.trim(starttime=stime, endtime=etime)
if wsgi:
if args['type'] == 'dayplot':
with warnings.catch_warnings():
warnings.simplefilter("ignore")
return trace_dayplot(st, outpattern=args['format'], wsgi=wsgi, deltat=deltat)
else:
return fancy_plot(st, wsgi=wsgi, img_format=args['format'], color=args['color'])
else:
if args['type'] == 'dayplot':
with warnings.catch_warnings():
warnings.simplefilter("ignore")
trace_dayplot(st, wsgi=wsgi)
else:
fancy_plot(st, color=args['color'])
elif not wsgi:
warnings.warn('No data available!')
def application(environ, start_response):
"""
Function application - Wrapper to process wsgi request
:param environ: contains information on the wsgi environment
:type environ: dict
:param start_response: function to process response header by the wsgi server
:type start_response: function
:return: response to be sent to the client by the wsgi server
:rtype: list
"""
import os
from cgi import FieldStorage
# set HOME environment variable to a directory the httpd server can write to
# otherwise matplotlib won't work
os.environ['HOME'] = '/tmp/wsgi-kasper'
try:
os.mkdir('/tmp/wsgi-kasper')
except OSError:
pass
# fake command line arguments
# setting needed default values
wsgi_args = {'server': 'http://localhost/'}
# fill wsgi_args with environment variables
form = FieldStorage(fp=environ['wsgi.input'], environ=environ)
wsgi_args['station'] = form.getfirst('station', 'GR.BUG').upper()
wsgi_args['stime'] = form.getfirst('start_time', [])
wsgi_args['length'] = form.getfirst('length', '30')
wsgi_args['length'] = abs(int(wsgi_args['length']))
wsgi_args['format'] = form.getfirst('format', 'png').lower()
if wsgi_args['format'] != 'png' and wsgi_args['format'] != 'svg':
wsgi_args['format'] = 'png'
wsgi_args['color'] = form.getfirst('color', 'TRUE').upper()
if wsgi_args['color'] == 'FALSE':
wsgi_args['color'] = False
else:
wsgi_args['color'] = True
wsgi_args['type'] = form.getfirst('type', '').lower()
if (wsgi_args['type'] != 'dayplot' and wsgi_args['type'] != 'normal') or wsgi_args['type'] == '':
if wsgi_args['length'] < 43200:
wsgi_args['type'] = 'normal'
else:
wsgi_args['type'] = 'dayplot'
# process the request
buf = main(args=wsgi_args, backend='Agg', wsgi=True)
if buf is not None:
data = buf.getvalue()
buf.close()
data_length = len(data)
if wsgi_args['format'] == 'svg':
wsgi_args['format'] = 'svg+xml'
start_response('200 OK', [('Content-Type', 'image/%s' % wsgi_args['format']), ('Content-Length', '%d' % data_length)])
return [data]
else:
start_response('400 Bad Request', [])
return []
# __main__
if __name__ == "__main__":
import os
import argparse
parser = argparse.ArgumentParser(
description=u'Get event waveform data of all RuhrNet stations.',
epilog=u'$Revision$ ($Date$, $Author$)'.replace(
"$", ""))
parser.add_argument(u'-v', u'-V', u'--version', action='version',
version=u'v1.1 (2021-10-31)')
parser.add_argument(u'-u', u'--url', action='store', dest='server',
default=u'https://ariadne.geophysik.ruhr-uni-bochum.de',
help=u'Base URL of the FDSN web service (https://ariadne.geophysik.ruhr-uni-bochum.de).')
parser.add_argument(u'-t', u'--type', action='store', dest='type', metavar='TYPE',
help=u'Type of plot: normal or dayplot.')
parser.add_argument(u'-f', u'--file', action='store', dest='filename', metavar='FILENAME',
help=u'Save plot to file FILENAME')
parser.add_argument(u'-c', u'--color', action='store_true', help=u'Create color plot.')
parser.add_argument(u'-l', u'--length', action='store', type=int, default=30,
help=u'Length of waveform window in seconds (30 s).')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument(u'-s', u'--start_time', dest='stime', action='store', metavar='START',
help=u'Start time of waveform window.')
group.add_argument(u'-e', u'--event', action='store', metavar='EVENTID',
help=u'Get starttime from event P-phase onset at station.')
parser.add_argument(u'station', action='store', metavar='NET.STATION',
help=u'Station to plot.')
cla = vars(parser.parse_args())
if os.getenv('DISPLAY'):
main(args=cla)
else:
main('Agg', cla)

View File

@ -1,19 +0,0 @@
def application(environ, start_response):
"""
Function application - Wrapper to process wsgi request
:param environ: contains information on the wsgi environment
:type environ: dict
:param start_response: function to process response header by the wsgi server
:type start_response: function
:return: response to be sent to the client by the wsgi server
:rtype: list
:version: v1.2 (2022-02-23)
"""
from cgi import FieldStorage
form = FieldStorage(fp=environ['wsgi.input'], environ=environ)
start_response('200 OK', [('Content-Type', 'text/html')])
return [form]

View File

@ -1,116 +0,0 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
"""
Produce a dayplot from seismogram recordings
version: v1.2 (2022-02-23)
license: gpl3
Copyright 2012-2020 Seismological Observatory, Ruhr-University Bochum
http://www.gmg.ruhr-uni-bochum.de/geophysik/seisobs
Contributors:
Martina Rische <martina.rische@rub.de>
Kasper D. Fischer <kasper.fischer@rub.de>
Sebastian Wehling-Benatelli <sebastian.wehling@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/.
"""
def trace_dayplot(st, ftype='bandpass', fmin=1.0, fmax=7.0,
col=('b', 'r', 'g'), interval=20.0, outpattern=''):
"""
:type st: object
:type ftype: str
:type fmin: float
:type fmax: float
:type col: tuple
:type interval: float
:type outpattern: str
"""
# filter
if (ftype == 'bandpass') or (ftype == 'bandstop'):
st.filter(ftype, freqmin=fmin, freqmax=fmax)
elif (ftype == 'lowpass') or (ftype == 'highpass'):
st.filter(ftype, freq=fmin)
st.merge()
# plot
for i in range(0, len(st)):
if outpattern != '':
imagefile = outpattern.format(st[i].stats.network,
st[i].stats.station,
st[i].stats.channel,
st[i].stats.starttime.year,
st[i].stats.starttime.julday)
st[i].plot(type='dayplot', color=col, interval=interval,
outfile=imagefile)
else:
st[i].plot(type='dayplot', color=col, interval=interval)
# __main__
if __name__ == "__main__":
# parse arguments
import argparse
from obspy.core import read
parser = argparse.ArgumentParser(
description='Produce filtered 24h-plot (dayplot).',
epilog='$Rev: 403 $ ($Date: 2012-04-13 12:16:22 +0200 (Fri, 13 Apr 2012) $, $Author: kasper $)')
parser.add_argument('-v', '-V', '--version', action='version',
version='$Rev: 403 $ ($Date: 2012-04-13 12:16:22 +0200 (Fri, 13 Apr 2012) $, $Author: kasper $)')
parser.add_argument('file', action='store', metavar='FILE', nargs='+',
help='File(s) to use for the dayplot. One dayplot will be used for every file. \
Use wildcards to use multiple file for one plot')
parser.add_argument('-f', '--filter', action='store', dest='ftype',
default='bandpass',
choices=['none', 'bandpass', 'bandstop', 'lowpass', 'highpass'],
help='Select filtertype to filter the data (default: bandpass)\
Note: For low- and highpass only fmin is used.')
parser.add_argument('--fmin', action='store', type=float, dest='fmin',
default=1.0,
help='Lower frequency of the filter in Hz (default: 1.0)')
parser.add_argument('--fmax', action='store', type=float, dest='fmax',
default=7.0,
help='Upper frequency of the filter in Hz (default: 7.0)')
parser.add_argument('-c', '--color', '--colour', action='store', dest='color',
default=('b', 'r', 'g'),
help='Color selection to use in the dayplot (default: brg)')
parser.add_argument('-i', '--interval', action='store', type=int, dest='interval',
default=20,
help='Interval length to show in each line of the dayplot in minutes (default: 20)')
parser.add_argument('-o', '--output', action='store', dest='outpattern',
default='',
help="Output filename pattern for the plot. (default: unset, show plot on screen only), \
Use {0} to substitute network code, \
{1} to substitute station code, \
{2} to substitute station channel, \
{3} to substitute year, \
{4} to substitute doy number \
.format (supported formats: emf, eps, pdf, png, ps, raw, rgba, svg, svgz)")
cla = parser.parse_args()
if cla.fmin < 0:
cla.fmin = -cla.fmin
if cla.fmax < 0:
cla.fmax = -cla.fmax
# call trace_dayplot(...) for each file
for datafile in cla.file:
trace_dayplot(read(datafile), cla.ftype, cla.fmin, cla.fmax, cla.color,
cla.interval, cla.outpattern)

View File

@ -1,54 +0,0 @@
<div class="accordioncontent">
<p >Das Urheberrecht der verwendeten Daten, Kartengrundlagen und
JavaScript Dateien liegt bei dem jeweiligen Urheber. Die
Benutzung unterliegt verschiedenen Lizenzen. Eine normale
Nutzung zur Darstellung im Internet ist dabei bei den benutzten
Quellen frei mögliche. Eine darüber hinaus gehende Nutzung (z.
B. drucken, speichern, Weiterverwendung in anderen Publikationen
etc.) ist nur unter <b>Beachtung der verschiedenen Lizenzen</b>
möglich. Diese sind im folgenden zusammengefasst.</p>
<h4>Kartengrundlage und Nominatim Dienst</h4>
<p>Die Kartengrundlagen und der Nominatim Dienst (reverse
Geocodierung) basieren auf Daten des <a
href="//www.openstreetmap.org" target="_blank">OpenStreetMap</a>
Projektes und wurden durch <a href="//www.mapquest.com/"
target="_blank">MapQuest</a> <img alt="Mapquest Logo"
src="//developer.mapquest.com/content/osm/mq_logo.png" /> zur
Verfügung gestellt. Hierfür gelten die „<a
href="//developer.mapquest.com/web/info/terms-of-use"
target="_blank">Terms of use</a>“ des Anbieters. Diese gestatten
eine nicht-kommerzielle, öffentlich zugängliche Nutzung.</p>
<h4>Ereignisdaten und Stationsdaten</h4>
<p>Die dargestellten Daten der seismischen Ereignisse und der
seismischen Stationen unterliegen der „<a
href="http://opendatacommons.org/licenses/odbl/summary"
target="_blank">Open Data Commons Open Database Lizenz</a>“
(ODbL). Die Daten dürfen frei kopieren, weitergegeben,
übermittel sowie angepasst werden, sofern das <a
href="http://www.gmg.ruhr-uni-bochum.de"
target="_blamk">Seismologische Observatorium der
Ruhr-Universität</a> als Quelle genannt wird. Werden diese Daten
wiederverwendet, so unterliegen sie weiterhin dieser Lizenz. Der
vollständige <a
href="http://opendatacommons.org/licenses/odbl/1.0/"
target="_blank">Lizenztext</a> erläutert die Rechte und
Pflichten dieser Lizenz.</p>
<h4>JavaScript Dateien</h4>
<p>Diese Webseite benutzt verschiedene JavaScript Bibliotheken,
die unterschiedlichen Lizenzen unterliegen. Die jeweiligen
Lizenzen werden in der Regel im Quellcode der benutzten
Bibliotheken aufgeführt.</p>
<h4>Sonstiger Inhalt</h4>
<p>Sonstiger Inhalt dieser Webseite unterliegt der
„Creative-Commons''-Lizenz „<a
href="https://creativecommons.org/licenses/by-sa/4.0/deed.de"
target="_blank">Namensnennung Weitergabe unter gleichen
Bedingungen</a>“ 4.0 (CC BY-SA). Der vollständige <a
href="https://creativecommons.org/licenses/by-sa/4.0/legalcode"
target="_blank">Lizenztext</a> erläutert die Rechte und
Pflichten dieser Lizenz.</p>
</div>

View File

View File

@ -1,12 +0,0 @@
/* last change 2022-20-23 */
var specialEvents = [
// 'bug2016ajgm', // CTBT violation North Korea
// 'bug2016qphy', // Central Italy 6.1
// 'bug2016rslt', // CTBT violation North Korea
// 'bug2016vico', // Central Italy 6.5
// 'bug2017rfxe', // CTBT violation North Korea 6.1
// 'bug2019fura', // Sprengung Duisburg-Hochheide (Weißer Riese) 2.0
// 'bug2021vtgi', // Geilenkirchen 1.9
// 'bug2022ahxi', // Erftstadt 2.9
'bug2023hlmh' // Brüggen 3.3
];

View File

@ -1,438 +0,0 @@
/**********************************************************************
* events.js *
* script for event specific functions and setup *
**********************************************************************/
/* License
Copyright 2014-2021 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/.
Version v1.3 (2023-04-17)
*/
/* adding row(s) to a table and format date strings afterwards */
function addTableRow(row, table) {
var added = $('#'+table+' tbody').append(row);
added.find('.tablesorter-childRow td').hide();
$('#'+table).find('td.utctime-date').each(function() {
$.localtime.formatObject($(this), "dd.MM.yyyy");
$(this).removeClass('utctime-date');
$(this).addClass('localtime-date');
});
$('#'+table).find('td.utctime-time').each(function() {
$.localtime.formatObject($(this), "HH:mm");
$(this).removeClass('utctime-time');
$(this).addClass('localtime-time');
});
};
/* do reverse geolocation lookup */
function getGeolocation(id, lat, lng) {
if ( $.inArray(id, geolocationTable) == -1 ) {
$.getJSON( config['ajax']['nominatimURL'], { lat: lat, lon: lng } )
.done(function( json ) {
if ( json.features[0] ) {
var city = json.features[0].properties.city;
var countryCode = json.features[0].properties.country;
geolocationTable[id] = city;
( countryCode != "Germany" && countryCode != "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, eventid, url, target) {
var mapBounds = map.getBounds();
var request_data = {};
var rtime;
var ajax_url = config['ajax']['eventURL'];
if ( stime == '' || !stime ) {
stime = new Date();
stime.setDate(stime.getDate()-config['map']['timespan']);
rtime = new Date();
rtime.setDate(rtime.getDate()-Math.min(config['ajax']['timespan'], config['map']['timespan']));
} else {
rtime = stime;
};
if ( url ) {
var ajax_url = url;
request_data = {};
} else {
if ( eventid ) {
request_data = { eventid: eventid };
} else {
request_data = {
starttime: sprintf("%d-%02d-%02d", rtime.getFullYear(), rtime.getMonth()+1, rtime.getDate()),
orderby: 'time-asc',
minlat: sprintf('%.2f', mapBounds.getSouth()-config['map']['latlngDelta']),
maxlat: sprintf('%.2f', mapBounds.getNorth()+config['map']['latlngDelta']),
minlon: sprintf('%.2f', mapBounds.getWest()-config['map']['latlngDelta']),
maxlon: sprintf('%.2f', mapBounds.getEast()+config['map']['latlngDelta']),
minmag: sprintf('%.1f', config['event']['minMag']-config['event']['minMagDelta']),
};
if ( etime ) {
request_data['endtime'] = sprintf("%d-%02d-%02d", etime.getFullYear(), etime.getMonth()+1, etime.getDate());
};
};
};
if ( etime == '' || !etime ) { etime = new Date(); };
$.ajax({
type: "GET",
url: ajax_url,
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 depth = $(this).find('origin > depth > value').text();
var evaluationMode = $(this).find('origin > evaluationMode').text();
var evaluationStatus = $(this).find('origin > evaluationStatus').text();
var type = $(this).find('type').last().text();
var location
// create table row: Date, Time, Mag, Location
if ( !eventTable[id] && $.inArray(type, config['event']['typeWhitelist'] ) >= 0 && $.inArray(evaluationStatus, config['event']['evaluationBlacklist'])<0 && Number(mag)+0.05 >= config['event']['minMag'] ) {
geolocationTable[id] ? null : getGeolocation(id, lat, lng); // do AJAX lookup if not cached, location will be updated later
location = ( geolocationTable[id] || getLocation(lat, lng)[0] || $(this).find('description > text').text() );
// general event info (1st line)
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>';
// setting up event details (2nd line)
row += '<tr class="tablesorter-childRow event-details">'
+ '<td colspan="4" eventid="'+id+'">Daten werden geladen ...</td></tr>';
// setting up download links (3nd line)
var xmlurl = sprintf('%s?formatted=true&includearrivals=true&eventid=%s', config['ajax']['eventURL'], id);
var oTime = new Date(otime);
if ( ~oTime ) {
oTime = new Date(otime.split('.')[0]);
};
var sTime = new Date(oTime.getTime()-10*1000.-oTime.getMilliseconds());
var eTime = new Date(oTime.getTime()+50*1000.-oTime.getMilliseconds());
var mseedurl = sprintf('%s?net=GE,GR,RN&cha=EH?,HH?&start=%04d-%02d-%02dT%02d:%02d:%02d&end=%04d-%02d-%02dT%02d:%02d:%02d', config['ajax']['mseedURL'], Number(sTime.getUTCFullYear()), Number(sTime.getUTCMonth())+1, Number(sTime.getUTCDate()), Number(sTime.getUTCHours()), Number(sTime.getUTCMinutes()), Number(sTime.getUTCSeconds()), Number(eTime.getUTCFullYear()), Number(eTime.getUTCMonth())+1, Number(eTime.getUTCDate()), Number(eTime.getUTCHours()), Number(eTime.getUTCMinutes()), Number(eTime.getUTCSeconds()));
row += '<tr class="tablesorter-childRow event-download">'
+ '<td colspan="4" eventid="'+id+'">'
+ sprintf('Download <a class="xml-link" target="_blank" download="%s.xml" href="%s">QuakeML</a> or <a class="mseed-link" target="_blank" download="%s.mseed" href="%s">miniSEED</a>', id, xmlurl, id, mseedurl)
+ '</td></tr>';
// add row to table
if ( stime <= oTime && etime >= oTime ) {
addTableRow(row, 'eventstable');
};
if ( target ) {
addTableRow(row, target);
}
// create marker
if ((stime <= oTime && etime >= oTime ) || ( id == eventid )) {
var marker = addEventMarker(id, Number(lat), Number(lng), Number(mag), type);
var text = sprintf('<h3 eventid="%s">%s</h3>', id, location)
+ sprintf('<p>Ereignis: %s<br />', id)
+ sprintf('Type: %s<br />', type)
+ sprintf('Magnitude: %3.1f<br />', Number(mag))
+ sprintf('Ort: %.4f °N, %.4f °O <br />', Number(lat), Number(lng))
+ sprintf('Tiefe: %.1f km<br />', Number(depth)/1000.)
+ sprintf('Zeit: <span class="utctime">%sZ</span></p>', otime.split('.')[0], otime.split('.')[0]);
marker.bindPopup(text);
};
};
});
},
complete: function () {
var sort = [[0,1],[1,1],[2,1]];
$("#eventstable").trigger("update", [true]);
$("#eventstable").trigger("updateCache");
$("#eventstable").trigger("sorton", [sort]);
initMapLink();
eventLayer.bringToBack();
highlightFirstEvent();
},
error: function( jqxhr, textStatus, error ) {
var err = textStatus + ", " + error;
console.log( "Request Failed: " + err );
}
});
// create events csv download link
request_data['format'] = 'text';
if ( eventid == '' || !eventid ) { $('#events-csv-link').attr('href', config['ajax']['eventURL']+'?'+$.param(request_data)) };
};
/* 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 event = $(this);
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();
// setting up general event info
var row = "<pre>"
+ sprintf("ID %49s\n", id)
+ sprintf("Type %47s\n\n", type)
+ "Origin\n"
+ 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("Magnitude %10.1f\n", Number(mag))
+ 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\n";
// adding phase info (TODO sort by distance)
$(this).find('origin > arrival').each(function() {
var pickid = $(this).find('pickID').text();
var azi = $(this).find('azimuth').text();
var dist = $(this).find('distance').text();
var tres = $(this).find('timeResidual').text();
var phase = $(this).find('phase').text();
var tweight = $(this).find('timeWeight').text();
if ( Number(tweight) > 0.0 ) {
var waveformid = event.find('pick[publicID="'+pickid+'"] > waveformID');
var networkcode = waveformid.attr('networkCode');
var stationcode = waveformid.attr('stationCode');
var channel = waveformid.attr('channelCode').substring(2,2);
var phasemode = event.find('pick[publicID="'+pickid+'"] > evaluationMode').text().substring(0,1).toUpperCase();
var picktime = event.find('pick[publicID="'+pickid+'"] > time > value').text().split('T')[1].substring(0,11);
row = row
+ sprintf('%-4s %2s %5.1f %5.1f %3s %1s %13s %5.1f %5.2f\n', stationcode, networkcode, Number(dist), Number(azi), phase, phasemode, picktime, Number(tres), Number(tweight));
};
});
row = row + '</pre>';
$('#eventstable > tbody > tr.event-details > td[eventid='+id+']').html(row);
});
},
complete: function () {
null;
},
error: function( jqxhr, textStatus, error ) {
var err = textStatus + ", " + error;
console.log( "Request Failed: " + err );
}
});
};
/* 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") ) {
map.addLayer(eventTable[$(this).attr("eventid")]);
};
});
// hide filtered events in map
$("#eventstable > tbody > tr.filtered > td > a.map-link").each( function() {
if ( $(this).attr("eventid") ) {
map.removeLayer(eventTable[$(this).attr("eventid")]);
};
});
highlightFirstEvent();
};
/* Highlight the first event of the event list on the map if no
* other event is selected */
function highlightFirstEvent() {
var highlightStyle = {
color: config['event']['markerColorH'],
fillColor: config['event']['markerColorH'],
fillOpacity: 1,
};
var normalStyle = {
fillColor: config['event']['markerColor'],
color: config['event']['markerColor'],
fillOpacity: config['event']['markerOpacity'],
};
$("#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):visible").first().find("a.map-link").each(function() {
if ( $(this).attr("eventid") ) {
eventTable[$(this).attr("eventid")].setStyle(highlightStyle);
eventTable[$(this).attr("eventid")].bringToFront();
$(this).addClass('first');
$(this).text('Karte (rot)');
};
});
};
function highlightEvent( id ) {
var highlightStyle = {
color: config['event']['markerColorH'],
fillColor: config['event']['markerColorH'],
fillOpacity: 1,
};
var normalStyle = {
fillColor: config['event']['markerColor'],
color: config['event']['markerColor'],
fillOpacity: config['event']['markerOpacity'],
};
$("#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);
eventTable[$(this).attr("eventid")].bringToFront();
$(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').on('filterEnd', function(){
toggleFilteredMarkers();
});
// highlight first event
$('#eventstable').on('sortEnd', function(){
highlightFirstEvent();
});
$('#eventstable').on('pagerComplete', function(){
highlightFirstEvent();
});
// show / hide event info
$('#eventstable').on('click', '.toggle', 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');
highlightFirstEvent();
} else {
$(this).addClass('selected');
highlightEvent($(this).attr('eventid'));
};
});
return false;
});
// update selection / type info
$("#events-timespan").text(config['map']['timespan']);
$("#events-minmag").text(sprintf('%.1f', config['event']['minMag']));
config['event']['typeWhitelist'].map(function(type) {
var typetext;
( $("#events-type").text() == "Symbole:" ) ? typetext = ' ' : typetext = ', ';
switch ( type ) {
case 'earthquake':
typetext += 'tektonisches Erdbeben&nbsp;(Stern)';
break;
case 'induced or triggered event':
typetext += '(bergbau-)induziertes Ereignis&nbsp;(Kreis)';
break;
case 'quarry blast':
case 'controlled explosion':
case 'explosion':
typetext += 'Sprengung&nbsp;(Rad)';
break;
case 'nuclear explosion':
typetext += 'Atomwaffentest&nbsp;(Viereck)';
break;
};
$("#events-type").append(typetext);
});
});

View File

@ -1,438 +0,0 @@
/**********************************************************************
* events.js.en *
* script for event specific functions and setup *
**********************************************************************/
/* License
Copyright 2014-2021 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/.
Version v1.3 (2023-04-17)
*/
/* adding row(s) to a table and format date strings afterwards */
function addTableRow(row, table) {
var added = $('#'+table+' tbody').append(row);
added.find('.tablesorter-childRow td').hide();
$('#'+table).find('td.utctime-date').each(function() {
$.localtime.formatObject($(this), "dd.MM.yyyy");
$(this).removeClass('utctime-date');
$(this).addClass('localtime-date');
});
$('#'+table).find('td.utctime-time').each(function() {
$.localtime.formatObject($(this), "HH:mm");
$(this).removeClass('utctime-time');
$(this).addClass('localtime-time');
});
};
/* do reverse geolocation lookup */
function getGeolocation(id, lat, lng) {
if ( $.inArray(id, geolocationTable) == -1 ) {
$.getJSON( config['ajax']['nominatimURL'], { lat: lat, lon: lng } )
.done(function( json ) {
if ( json.features[0] ) {
var city = json.features[0].properties.city;
var countryCode = json.features[0].properties.country;
geolocationTable[id] = city;
( countryCode != "Germany" && countryCode != "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, eventid, url, target) {
var mapBounds = map.getBounds();
var request_data = {};
var rtime;
var ajax_url = config['ajax']['eventURL'];
if ( stime == '' || !stime ) {
stime = new Date();
stime.setDate(stime.getDate()-config['map']['timespan']);
rtime = new Date();
rtime.setDate(rtime.getDate()-Math.min(config['ajax']['timespan'], config['map']['timespan']));
} else {
rtime = stime;
};
if ( url ) {
var ajax_url = url;
request_data = {};
} else {
if ( eventid ) {
request_data = { eventid: eventid };
} else {
request_data = {
starttime: sprintf("%d-%02d-%02d", rtime.getFullYear(), rtime.getMonth()+1, rtime.getDate()),
orderby: 'time-asc',
minlat: sprintf('%.2f', mapBounds.getSouth()-config['map']['latlngDelta']),
maxlat: sprintf('%.2f', mapBounds.getNorth()+config['map']['latlngDelta']),
minlon: sprintf('%.2f', mapBounds.getWest()-config['map']['latlngDelta']),
maxlon: sprintf('%.2f', mapBounds.getEast()+config['map']['latlngDelta']),
minmag: sprintf('%.1f', config['event']['minMag']-config['event']['minMagDelta']),
};
if ( etime ) {
request_data['endtime'] = sprintf("%d-%02d-%02d", etime.getFullYear(), etime.getMonth()+1, etime.getDate());
};
};
};
if ( etime == '' || !etime ) { etime = new Date(); };
$.ajax({
type: "GET",
url: ajax_url,
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 depth = $(this).find('origin > depth > value').text();
var evaluationMode = $(this).find('origin > evaluationMode').text();
var evaluationStatus = $(this).find('origin > evaluationStatus').text();
var type = $(this).find('type').last().text();
var location
// create table row: Date, Time, Mag, Location
if ( !eventTable[id] && $.inArray(type, config['event']['typeWhitelist'] ) >= 0 && $.inArray(evaluationStatus, config['event']['evaluationBlacklist'])<0 && Number(mag)+0.05 >= config['event']['minMag'] ) {
geolocationTable[id] ? null : getGeolocation(id, lat, lng); // do AJAX lookup if not cached, location will be updated later
location = ( geolocationTable[id] || getLocation(lat, lng)[0] || $(this).find('description > text').text() );
// general event info (1st line)
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+'">map</a></td>'
+ '</tr>';
// setting up event details (2nd line)
row += '<tr class="tablesorter-childRow event-details">'
+ '<td colspan="4" eventid="'+id+'">Daten werden geladen ...</td></tr>';
// setting up download links (3nd line)
var xmlurl = sprintf('%s?formatted=true&includearrivals=true&eventid=%s', config['ajax']['eventURL'], id);
var oTime = new Date(otime);
if ( ~oTime ) {
oTime = new Date(otime.split('.')[0]);
};
var sTime = new Date(oTime.getTime()-10*1000.-oTime.getMilliseconds());
var eTime = new Date(oTime.getTime()+50*1000.-oTime.getMilliseconds());
var mseedurl = sprintf('%s?net=GE,GR,RN&cha=EH?,HH?&start=%04d-%02d-%02dT%02d:%02d:%02d&end=%04d-%02d-%02dT%02d:%02d:%02d', config['ajax']['mseedURL'], Number(sTime.getUTCFullYear()), Number(sTime.getUTCMonth())+1, Number(sTime.getUTCDate()), Number(sTime.getUTCHours()), Number(sTime.getUTCMinutes()), Number(sTime.getUTCSeconds()), Number(eTime.getUTCFullYear()), Number(eTime.getUTCMonth())+1, Number(eTime.getUTCDate()), Number(eTime.getUTCHours()), Number(eTime.getUTCMinutes()), Number(eTime.getUTCSeconds()));
row += '<tr class="tablesorter-childRow event-download">'
+ '<td colspan="4" eventid="'+id+'">'
+ sprintf('Download <a class="xml-link" target="_blank" download="%s.xml" href="%s">QuakeML</a> or <a class="mseed-link" target="_blank" download="%s.mseed" href="%s">miniSEED</a>', id, xmlurl, id, mseedurl)
+ '</td></tr>';
// add row to table
if ( stime <= oTime && etime >= oTime ) {
addTableRow(row, 'eventstable');
};
if ( target ) {
addTableRow(row, target);
}
// create marker
if ((stime <= oTime && etime >= oTime ) || ( id == eventid )) {
var marker = addEventMarker(id, Number(lat), Number(lng), Number(mag), type);
var text = sprintf('<h3 eventid="%s">%s</h3>', id, location)
+ sprintf('<p>Ereignis: %s<br />', id)
+ sprintf('Type: %s<br />', type)
+ sprintf('Magnitude: %3.1f<br />', Number(mag))
+ sprintf('Ort: %.4f °N, %.4f °O <br />', Number(lat), Number(lng))
+ sprintf('Tiefe: %.1f km<br />', Number(depth)/1000.)
+ sprintf('Zeit: <span class="utctime">%sZ</span></p>', otime.split('.')[0], otime.split('.')[0]);
marker.bindPopup(text);
};
};
});
},
complete: function () {
var sort = [[0,1],[1,1],[2,1]];
$("#eventstable").trigger("update", [true]);
$("#eventstable").trigger("updateCache");
$("#eventstable").trigger("sorton", [sort]);
initMapLink();
eventLayer.bringToBack();
highlightFirstEvent();
},
error: function( jqxhr, textStatus, error ) {
var err = textStatus + ", " + error;
console.log( "Request Failed: " + err );
}
});
// create events csv download link
request_data['format'] = 'text';
if ( eventid == '' || !eventid ) { $('#events-csv-link').attr('href', config['ajax']['eventURL']+'?'+$.param(request_data)) };
};
/* 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 event = $(this);
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();
// setting up general event info
var row = "<pre>"
+ sprintf("ID %49s\n", id)
+ sprintf("Type %47s\n\n", type)
+ "Origin\n"
+ 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("Magnitude %10.1f\n", Number(mag))
+ 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\n";
// adding phase info (TODO sort by distance)
$(this).find('origin > arrival').each(function() {
var pickid = $(this).find('pickID').text();
var azi = $(this).find('azimuth').text();
var dist = $(this).find('distance').text();
var tres = $(this).find('timeResidual').text();
var phase = $(this).find('phase').text();
var tweight = $(this).find('timeWeight').text();
if ( Number(tweight) > 0.0 ) {
var waveformid = event.find('pick[publicID="'+pickid+'"] > waveformID');
var networkcode = waveformid.attr('networkCode');
var stationcode = waveformid.attr('stationCode');
var channel = waveformid.attr('channelCode').substring(2,2);
var phasemode = event.find('pick[publicID="'+pickid+'"] > evaluationMode').text().substring(0,1).toUpperCase();
var picktime = event.find('pick[publicID="'+pickid+'"] > time > value').text().split('T')[1].substring(0,11);
row = row
+ sprintf('%-4s %2s %5.1f %5.1f %3s %1s %13s %5.1f %5.2f\n', stationcode, networkcode, Number(dist), Number(azi), phase, phasemode, picktime, Number(tres), Number(tweight));
};
});
row = row + '</pre>';
$('#eventstable > tbody > tr.event-details > td[eventid='+id+']').html(row);
});
},
complete: function () {
null;
},
error: function( jqxhr, textStatus, error ) {
var err = textStatus + ", " + error;
console.log( "Request Failed: " + err );
}
});
};
/* 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") ) {
map.addLayer(eventTable[$(this).attr("eventid")]);
};
});
// hide filtered events in map
$("#eventstable > tbody > tr.filtered > td > a.map-link").each( function() {
if ( $(this).attr("eventid") ) {
map.removeLayer(eventTable[$(this).attr("eventid")]);
};
});
highlightFirstEvent();
};
/* Highlight the first event of the event list on the map if no
* other event is selected */
function highlightFirstEvent() {
var highlightStyle = {
color: config['event']['markerColorH'],
fillColor: config['event']['markerColorH'],
fillOpacity: 1,
};
var normalStyle = {
fillColor: config['event']['markerColor'],
color: config['event']['markerColor'],
fillOpacity: config['event']['markerOpacity'],
};
$("#eventstable a.map-link").each( function() {
if ( $(this).attr("eventid") ) {
eventTable[$(this).attr("eventid")].setStyle(normalStyle);
$(this).removeClass('first');
$(this).text('map');
};
});
$("#eventstable > tbody > tr:not(.filtered):visible").first().find("a.map-link").each(function() {
if ( $(this).attr("eventid") ) {
eventTable[$(this).attr("eventid")].setStyle(highlightStyle);
eventTable[$(this).attr("eventid")].bringToFront();
$(this).addClass('first');
$(this).text('map (red)');
};
});
};
function highlightEvent( id ) {
var highlightStyle = {
color: config['event']['markerColorH'],
fillColor: config['event']['markerColorH'],
fillOpacity: 1,
};
var normalStyle = {
fillColor: config['event']['markerColor'],
color: config['event']['markerColor'],
fillOpacity: config['event']['markerOpacity'],
};
$("#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);
eventTable[$(this).attr("eventid")].bringToFront();
$(this).addClass('first');
$(this).text('map (red)');
} else {
eventTable[$(this).attr("eventid")].setStyle(normalStyle);
$(this).removeClass('first');
$(this).text('map');
}
};
});
};
/**********************************************************************
* 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}) | page {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').on('filterEnd', function(){
toggleFilteredMarkers();
});
// highlight first event
$('#eventstable').on('sortEnd', function(){
highlightFirstEvent();
});
$('#eventstable').on('pagerComplete', function(){
highlightFirstEvent();
});
// show / hide event info
$('#eventstable').on('click', '.toggle', 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');
highlightFirstEvent();
} else {
$(this).addClass('selected');
highlightEvent($(this).attr('eventid'));
};
});
return false;
});
// update selection / type info
$("#events-timespan").text(config['map']['timespan']);
$("#events-minmag").text(sprintf('%.1f', config['event']['minMag']));
config['event']['typeWhitelist'].map(function(type) {
var typetext;
( $("#events-type").text() == "Symbols:" ) ? typetext = ' ' : typetext = ', ';
switch ( type ) {
case 'earthquake':
typetext += 'tectonic earthquake&nbsp;(star)';
break;
case 'induced or triggered event':
typetext += '(mining-)induced event&nbsp;(circle)';
break;
case 'quarry blast':
case 'controlled explosion':
case 'explosion':
typetext += 'quarry blast&nbsp;(wheel)';
break;
case 'nuclear explosion':
typetext += 'nuclear weapon test&nbsp;(square)';
break;
};
$("#events-type").append(typetext);
});
});

BIN
www/external/first.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 720 B

View File

@ -1,4 +0,0 @@
/*! jQuery localtime - v0.9.1 - 2014-01-11
* https://github.com/GregDThomas/jquery-localtime
* Copyright (c) 2014 Greg Thomas; Licensed Apache-2.0 */
(function(e){"use strict";e.localtime=function(){var a={localtime:"yyyy-MM-dd HH:mm:ss"},t=["January","February","March","April","May","June","July","August","September","October","November","December"],r=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],c=["th","st","nd","rd"],s=function(e){return e>=13?e-12:"0"===e?12:e},i=function(e,i){var o=""+e.getFullYear(),n=""+(e.getMonth()+1),l=""+e.getDate(),m=e.getDay(),d=""+e.getHours(),u=""+e.getMinutes(),b=""+e.getSeconds(),f=""+e.getMilliseconds(),k=e.getTimezoneOffset(),h=k>0?"-":"+";if(k=Math.abs(k),void 0===i){var y;for(y in a)if(a.hasOwnProperty(y)){i=a[y];break}if(void 0===i)return""+e}for(var g="",p="",M=0;i.length>M;M++)if(p+=i.charAt(M),"'"===p)for(M++;i.length>M;M++){var T=i.charAt(M);if("'"===T){p="";break}g+=T}else if("\\"===p&&i.length-1>M&&"'"===i.charAt(M+1))M++,g+="'",p="";else if(M===i.length-1||i.charAt(M)!==i.charAt(M+1)){switch(p){case"d":g+=l;break;case"dd":g+=("0"+l).slice(-2);break;case"ddd":g+=r[m].substr(0,3);break;case"ddddd":g+=r[m];break;case"M":g+=n;break;case"MM":g+=("0"+n).slice(-2);break;case"MMM":g+=t[n-1].substr(0,3);break;case"MMMMM":g+=t[n-1];break;case"yy":g+=o.slice(-2);break;case"yyyy":g+=o;break;case"H":g+=d;break;case"HH":g+=("0"+d).slice(-2);break;case"h":g+=s(d);break;case"hh":g+=("0"+s(d)).slice(-2);break;case"m":g+=u;break;case"mm":g+=("0"+u).slice(-2);break;case"s":g+=b;break;case"ss":g+=("0"+b).slice(-2);break;case"S":g+=f;break;case"SS":g+=("0"+f).slice(-2);break;case"SSS":g+=("00"+f).slice(-3);break;case"o":switch(l){case"11":case"12":case"13":g+=c[0];break;default:var v=l%10;v>3&&(v=0),g+=c[v]}break;case"a":case"TT":g+=d>=12?"PM":"AM";break;case"tt":g+=d>=12?"pm":"am";break;case"T":g+=d>=12?"P":"A";break;case"t":g+=d>=12?"p":"a";break;case"z":g+=h+parseInt(k/60,10);break;case"zz":g+=h+("0"+parseInt(k/60,10)).slice(-2);break;case"zzz":g+=h+("0"+parseInt(k/60,10)).slice(-2)+":"+("0"+k%60).slice(-2);break;default:g+=p}p=""}return g};return{setFormat:function(e){a="object"==typeof e?e:{localtime:e}},getFormat:function(){return a},parseISOTimeString:function(a){a=e.trim(""+a);var t=/^(\d{4})-([01]\d)-([0-3]\d)[T| ]([0-2]\d):([0-5]\d)(?::([0-5]\d)(?:\.(\d{3}))?)?Z$/.exec(a);if(t){var r=parseInt(t[1],10),c=parseInt(t[2],10)-1,s=parseInt(t[3],10),i=parseInt(t[4],10),o=parseInt(t[5],10),n=t[6]?parseInt(t[6],10):0,l=t[7]?parseInt(t[7],10):0,m=new Date(Date.UTC(r,c,s,i,o,n,l));if(m.getUTCFullYear()!==r||m.getUTCMonth()!==c||m.getUTCDate()!==s)throw Error(t[1]+"-"+t[2]+"-"+t[3]+" is not a valid date");if(m.getUTCHours()!==i)throw Error(t[4]+":"+t[5]+" is not a valid time");return m}throw Error(a+" is not a supported date/time string")},toLocalTime:function(a,t){return"[object Date]"!==Object.prototype.toString.call(a)&&(a=e.localtime.parseISOTimeString(a)),""===t&&(t=void 0),i(a,t)},formatObject:function(a,t){a.is(":input")?a.val(e.localtime.toLocalTime(a.val(),t)):a.is("time")?a.text(e.localtime.toLocalTime(a.attr("datetime"),t)):a.text(e.localtime.toLocalTime(a.text(),t))},formatPage:function(){e.localtime.format()},format:function(a){var t,r,c=function(){e.localtime.formatObject(e(this),t)},s=e.localtime.getFormat();for(r in s)s.hasOwnProperty(r)&&(t=s[r],e("."+r,a).each(c));e("[data-localtime-format]",a).each(function(){e.localtime.formatObject(e(this),e(this).attr("data-localtime-format"))})}}}()})(jQuery),jQuery(document).ready(function(e){"use strict";e.localtime.format()});

BIN
www/external/last.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 737 B

BIN
www/external/next.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 736 B

BIN
www/external/prev.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 745 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

View File

@ -1,29 +0,0 @@
<div class="accordioncontent">
<h4>Anschrift</h4>
Seismologisches Observatorium der<br />
Ruhr-Universität Bochum<br />
NA 3/174<br />
44780 Bochum<br />
Tel.: 0234 32-27574<br />
Fax: 0234 32-07574<br />
<p>Die Ruhr-Universität ist eine Körperschaft des Öffentlichen Rechts. Sie wird durch ihren Rektor Herrn Prof. Dr. Elmar W. Weiler gesetzlich vertreten.</p>
<p>Zuständige Aufsichtsbehörde ist das Ministerium für Innovation, Wissenschaft und Forschung des Landes Nordrhein-Westfalen, Völklinger Straße 49, 40221 Düsseldorf.</p>
<p>Umsatzsteuer-Identifikationsnummer: DE 127 056 261</p>
<h4>Inhaltliche und technische Verantwortung für die Seiten des Seismologischen Observatoriums der Ruhr-Universität Bochum</h4>
Herr Dr. Kasper D. Fischer<br />
Ruhr-Universität Bochum<br />
44780 Bochum<br />
Tel.: 0234 32-27574<br />
Fax: 0234 32-07574<br />
E-Mail: kasper.fischer@ruhr-uni-bochum.de<br />
<p>Meldungen über missbräuchliche Nutzungen, die von Stationen aus dem IP-Namensbereich ruhr-uni-bochum.de ausgehen, senden Sie bitte an die Email-Adresse
abuse@ruhr-uni-bochum.de. Gleichfalls bittet die Ruhr-Universität um Mitteilung an dieselbe Email-Adresse, wenn rechtswidrige Inhalte durch Links auf Seiten der Ruhr-Universität zu
erreichen sind.</p>
<h4>Rechtliche Hinweise</h4>
<p>Die Ruhr-Universität Bochum übernimmt keine Gewähr für die Richtigkeit und Vollständigkeit der auf ihren Internetseiten befindlichen Informationen. Das gleiche gilt für die
Inhalte verlinkter Seiten.</p>
</div>

View File

@ -1,179 +0,0 @@
<!DOCTYPE html>
<!-- Version v1.3 (2023-04-17) -->
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='de' lang='de'>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>RUB SeisObs - Ereignis- und Stationskarte</title>
<!-- Style definitions -->
<link rel="stylesheet" href="main.css" />
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/cupertino/jquery-ui.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/css/theme.blue.min.css" integrity="sha512-jJ9r3lTLaH5XXa9ZOsCQU8kLvxdAVzyTWO/pnzdZrshJQfnw1oevJFpoyCDr7K1lqt1hUgqoxA5e2PctVtlSTg==" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/css/jquery.tablesorter.pager.min.css" integrity="sha512-TWYBryfpFn3IugX13ZCIYHNK3/2sZk3dyXMKp3chZL+0wRuwFr1hDqZR9Qd5SONzn+Lja10hercP2Xjuzz5O3g==" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet-dvf/0.3.1/css/dvf.min.css" integrity="sha512-Ts/IYE5D8PaMBUDHcf6O57lOiV923cai3sEXo0WjhakpTxlwodQQJx1YA2t1mDUKO6fIXEngkKFLQNMXK/kBZg==" crossorigin="anonymous" />
<!-- jQuery & jQueryUI -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>
<!-- Localtime, sprintf, showdown -->
<script type="text/javascript" src="external/jquery.localtime-0.9.1.min.js"></script> <!-- current 2020-07-15 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/sprintf/1.1.2/sprintf.min.js" integrity="sha512-pmG0OkYtZVB2EqETE5HPsEaok7sNZFfStp5rNdpHv0tGQjbt1z8Qjzhtx88/4wsttOtDwq5DZGJyKyzEe7ribg==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/1.9.1/showdown.min.js" integrity="sha512-L03kznCrNOfVxOUovR6ESfCz9Gfny7gihUX/huVbQB9zjODtYpxaVtIaAkpetoiyV2eqWbvxMH9fiSv5enX7bw==" crossorigin="anonymous"></script>
<!-- Tablesorter -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/jquery.tablesorter.min.js" integrity="sha512-qzgd5cYSZcosqpzpn7zF2ZId8f/8CHmFKZ8j7mU4OUXTNRd5g+ZHBPsgKEwoqxCtdQvExE5LprwwPAgoicguNg==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/jquery.tablesorter.widgets.min.js" integrity="sha512-dj/9K5GRIEZu+Igm9tC16XPOTz0RdPk9FGxfZxShWf65JJNU2TjbElGjuOo3EhwAJRPhJxwEJ5b+/Ouo+VqZdQ==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/widgets/widget-pager.min.js" integrity="sha512-+X/dsto9+7foPuqwqjm+mJSPYk6Coovg9jQJvM+aBfscXOyBrAKN69GS5Z2TkMLlVHxeiE5doVqelnMfbsS9XQ==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/extras/jquery.tablesorter.pager.min.js" integrity="sha512-y845ijdup9lDunrcSRQAlFdQICHVhkB5UNguWRX8A3L+guxO7Oow0poojw0PLckhcKij++h85bnyro80fjR9+A==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/widgets/widget-scroller.min.js" integrity="sha512-1D2qKse1/4gCgLbgmBBv+9fJluAeJIlDgzIyZkovd1xmoyh1SW30lMIzCrD2X8Xs/sIzitUNDy86YagJRSUmaA==" crossorigin="anonymous"></script>
<!-- Leaflet -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-dvf/0.3.1/leaflet-dvf.markers.min.js" integrity="sha512-R/iucaxFnDFUTdZRxUvxzc+sypDQhqnxInBmNjgGE0RaiMl/ektVB1wFS/L0xDZmLFPpEGR0Kw3GEBgtQNFHyg==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-providers/1.13.0/leaflet-providers.min.js" integrity="sha512-5EYsvqNbFZ8HX60keFbe56Wr0Mq5J1RrA0KdVcfGDhnjnzIRsDrT/S3cxdzpVN2NGxAB9omgqnlh4/06TvWCMw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/leaflet.browser.print@1.0.6/dist/leaflet.browser.print.min.js" integrity="sha256-LrZphoL6+XVEuBR4BfhOIdRAMpRigQvsu3/iCNhQSXw=" crossorigin="anonymous"></script>
<script src="https://www.mapquestapi.com/sdk/leaflet/v2.2/mq-map.js?key=RPOPuz3lA2GGBtVpEU0ugxtVoGba53Dt"></script>
<!-- Map, Events & Stations -->
<script type="text/javascript" src="misc.js"></script>
<script type="text/javascript" src="map.js"></script>
<script type="text/javascript" src="events.js"></script>
<script type="text/javascript" src="stations.js"></script>
<script type="text/javascript" src="data/geolocation.js"></script>
<script type="text/javascript" src="data/specialevents.js"></script>
</head>
<body>
<!-- noscript -->
<noscript>
<div class="noscript">
<div class="noscriptcontent">
<h2>Kein JavaScript verfügbar!</h2>
<p>Diese Seite benötigt JavaScript. Bitte schalten Sie JavaScript ein.</p>
<h2>JavaScript disabled!</h2>
<p>This page requires JavaScript to work. Please enable JavaScript.</p>
<h2>Impressum</h2>
<!--#include virtual="impressum.inc.de" -->
</div>
</div>
</noscript>
<!-- Tabs -->
<div class="info" id="tabs">
<ul>
<li><a href="#eventstab"><span>Ereignisse</span></a></li>
<li><a href="#stationstab"><span>Stationen</span></a></li>
<li><a href="#moretab"><span>Mehr</span></a></li>
<li class="infotab"><a href="#infotab"><span>Info</span></a></li>
</ul>
<!-- Ereignisse -->
<div class="tab" id="eventstab">
<div class="pager events" id="eventspager">
<img src="external/first.png" class="first" alt="First" />
<img src="external/prev.png" class="prev" alt="Prev" />
<span class="pagedisplay"></span>
<img src="external/next.png" class="next" alt="Next" />
<img src="external/last.png" class="last" alt="Last" />
<select class="pagesize" title="Select page size">
<option value="5">5</option>
<option value="10">10</option>
<option value="15">15</option>
<option value="20">20</option>
<option value="25">25</option>
<option value="30">30</option>
<option value="35">35</option>
</select>
<select class="gotoPage" title="Select page number"></select>
</div>
<table class="tablesorter" id="eventstable">
<colgroup>
<col width="85" />
<col width="50" />
<col width="50" />
<col />
</colgroup>
<thead>
<tr>
<th>Datum</th>
<th>Zeit</th>
<th>Mag.</th>
<th>Ort</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<p class="table-caption">
Ereignisse der letzten <span id="events-timespan">180</span> Tage ab Magnitude <span id="events-minmag">1.2</span> im Bereich der Karte und besondere Ereignisse in angrenzenden Bereichen. Download als <a id="events-csv-link" href="link" download="events.csv">CSV-Datei</a>.
</p>
<p class="table-caption">
<span id="events-type">Symbole:</span>
</p>
<p class="table-caption">
Reverse Geolocation courtesy of <a href="http://photon.komoot.io/" target="_blank">Photon by Komoot</a>
</p>
</div>
<!-- Stations -->
<div class="tab" id="stationstab">
<div class="pager stationspager" id="stationspager">
<img src="external/first.png" class="stationsfirst" alt="First" />
<img src="external/prev.png" class="stationsprev" alt="Prev" />
<span class="stationspagedisplay"></span>
<img src="external/next.png" class="stationsnext" alt="Next" />
<img src="external/last.png" class="stationslast" alt="Last" />
<select class="stationspagesize" title="Select page size">
<option value="5">5</option>
<option value="10">10</option>
<option value="15">15</option>
<option value="20">20</option>
<option value="25">25</option>
<option value="30">30</option>
<option value="35">35</option>
</select>
<select class="stationsgotoPage" title="Select page number"></select>
</div>
<table class="tablesorter" id="stationstable">
<colgroup>
<col width="77" />
<col/>
<col width="77" align="char" char="." />
<col width="77" align="char" char="." />
</colgroup>
<thead>
<tr>
<th>Network</th>
<th>Station</th>
<th>Breite [°]</th>
<th>Länge [°]</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<p class="table-caption">Download als <a id="stations-csv-link" href="link" download="stations.csv">CSV-Datei</a>.</p>
</div>
<!-- More -->
<div class="tab more_de" id="moretab">
<p>Text wird geladen ...</p>
</div>
<!-- Info -->
<div class="tab" id="infotab">
<div id="infoaccordion">
<h3 class="aheader">Navigation / Links</h3>
<div class="info_de"><p>Text wird geladen ...</p></div>
<h3 class="aheader">Copyright / Lizenz</h3>
<div class="copyright_de"><p>Text wird geladen ...</p></div>
<h3 class="aheader">Impressum</h3>
<div class="imprint_de"><p>Text wird geladen ...</p></div>
</div>
</div>
</div>
<!-- Logo -->
<div class="rublogo"><a href="http://www.gmg.ruhr-uni-bochum.de/seisobs"><img class="rublogo" src="logo_RUB_155x30.png" alt="Ruhr-Universität Bochum" title="Ruhr-Universität Bochum" border="0"/></a></div>
<!-- Map -->
<div id="map" class="map"></div>
<div id="spinner" class="spinner" style="display:none;"><img id="img-spinner" src="spinner.gif" alt="Loading"/><br />Loading ...</div>
</body>
</html>

View File

@ -1,180 +0,0 @@
<!DOCTYPE html>
<!-- Version v1.3 (2023-04-17) -->
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='de' lang='de'>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>RUB SeisObs - Event and Station Map</title>
<!-- Style definitions -->
<link rel="stylesheet" href="main.css" />
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/cupertino/jquery-ui.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/css/theme.blue.min.css" integrity="sha512-jJ9r3lTLaH5XXa9ZOsCQU8kLvxdAVzyTWO/pnzdZrshJQfnw1oevJFpoyCDr7K1lqt1hUgqoxA5e2PctVtlSTg==" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/css/jquery.tablesorter.pager.min.css" integrity="sha512-TWYBryfpFn3IugX13ZCIYHNK3/2sZk3dyXMKp3chZL+0wRuwFr1hDqZR9Qd5SONzn+Lja10hercP2Xjuzz5O3g==" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet-dvf/0.3.1/css/dvf.min.css" integrity="sha512-Ts/IYE5D8PaMBUDHcf6O57lOiV923cai3sEXo0WjhakpTxlwodQQJx1YA2t1mDUKO6fIXEngkKFLQNMXK/kBZg==" crossorigin="anonymous" />
<!-- jQuery & jQueryUI -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>
<!-- Localtime, sprintf, showdown -->
<script type="text/javascript" src="external/jquery.localtime-0.9.1.min.js"></script> <!-- current 2020-07-15 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/sprintf/1.1.2/sprintf.min.js" integrity="sha512-pmG0OkYtZVB2EqETE5HPsEaok7sNZFfStp5rNdpHv0tGQjbt1z8Qjzhtx88/4wsttOtDwq5DZGJyKyzEe7ribg==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/1.9.1/showdown.min.js" integrity="sha512-L03kznCrNOfVxOUovR6ESfCz9Gfny7gihUX/huVbQB9zjODtYpxaVtIaAkpetoiyV2eqWbvxMH9fiSv5enX7bw==" crossorigin="anonymous"></script>
<!-- Tablesorter -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/jquery.tablesorter.min.js" integrity="sha512-qzgd5cYSZcosqpzpn7zF2ZId8f/8CHmFKZ8j7mU4OUXTNRd5g+ZHBPsgKEwoqxCtdQvExE5LprwwPAgoicguNg==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/jquery.tablesorter.widgets.min.js" integrity="sha512-dj/9K5GRIEZu+Igm9tC16XPOTz0RdPk9FGxfZxShWf65JJNU2TjbElGjuOo3EhwAJRPhJxwEJ5b+/Ouo+VqZdQ==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/widgets/widget-pager.min.js" integrity="sha512-+X/dsto9+7foPuqwqjm+mJSPYk6Coovg9jQJvM+aBfscXOyBrAKN69GS5Z2TkMLlVHxeiE5doVqelnMfbsS9XQ==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/extras/jquery.tablesorter.pager.min.js" integrity="sha512-y845ijdup9lDunrcSRQAlFdQICHVhkB5UNguWRX8A3L+guxO7Oow0poojw0PLckhcKij++h85bnyro80fjR9+A==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/widgets/widget-scroller.min.js" integrity="sha512-1D2qKse1/4gCgLbgmBBv+9fJluAeJIlDgzIyZkovd1xmoyh1SW30lMIzCrD2X8Xs/sIzitUNDy86YagJRSUmaA==" crossorigin="anonymous"></script>
<!-- Leaflet -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-dvf/0.3.1/leaflet-dvf.markers.min.js" integrity="sha512-R/iucaxFnDFUTdZRxUvxzc+sypDQhqnxInBmNjgGE0RaiMl/ektVB1wFS/L0xDZmLFPpEGR0Kw3GEBgtQNFHyg==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-providers/1.13.0/leaflet-providers.min.js" integrity="sha512-5EYsvqNbFZ8HX60keFbe56Wr0Mq5J1RrA0KdVcfGDhnjnzIRsDrT/S3cxdzpVN2NGxAB9omgqnlh4/06TvWCMw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/leaflet.browser.print@1.0.6/dist/leaflet.browser.print.min.js" integrity="sha256-LrZphoL6+XVEuBR4BfhOIdRAMpRigQvsu3/iCNhQSXw=" crossorigin="anonymous"></script>
<script src="https://www.mapquestapi.com/sdk/leaflet/v2.2/mq-map.js?key=RPOPuz3lA2GGBtVpEU0ugxtVoGba53Dt"></script>
<!-- Map, Events & Stations -->
<script type="text/javascript" src="misc.js"></script>
<script type="text/javascript" src="map.js.en"></script>
<script type="text/javascript" src="events.js.en"></script>
<script type="text/javascript" src="stations.js.en"></script>
<script type="text/javascript" src="data/geolocation.js"></script>
<script type="text/javascript" src="data/specialevents.js"></script>
</head>
<body>
<!-- noscript -->
<noscript>
<div class="noscript">
<div class="noscriptcontent">
<h2>JavaScript disabled!</h2>
<p>This page requires JavaScript to work. Please enable JavaScript.</p>
<h2>Kein JavaScript verfügbar!</h2>
<p>Diese Seite benötigt JavaScript. Bitte schalten Sie JavaScript ein.</p>
<h2>Impressum</h2>
<!--#include virtual="impressum.inc.de" -->
</div>
</div>
</noscript>
<!-- Tabs -->
<div class="info" id="tabs">
<ul>
<li><a href="#eventstab"><span>Events</span></a></li>
<li><a href="#stationstab"><span>Stations</span></a></li>
<li><a href="#moretab"><span>More</span></a></li>
<li class="infotab"><a href="#infotab"><span>Info</span></a></li>
</ul>
<!-- Ereignisse -->
<div class="tab" id="eventstab">
<div class="pager events" id="eventspager">
<img src="external/first.png" class="first" alt="First" />
<img src="external/prev.png" class="prev" alt="Prev" />
<span class="pagedisplay"></span>
<img src="external/next.png" class="next" alt="Next" />
<img src="external/last.png" class="last" alt="Last" />
<select class="pagesize" title="Select page size">
<option value="5">5</option>
<option value="10">10</option>
<option value="15">15</option>
<option value="20">20</option>
<option value="25">25</option>
<option value="30">30</option>
<option value="35">35</option>
</select>
<select class="gotoPage" title="Select page number"></select>
</div>
<table class="tablesorter" id="eventstable">
<colgroup>
<col width="85" />
<col width="50" />
<col width="50" />
<col />
</colgroup>
<thead>
<tr>
<th>Date</th>
<th>Time</th>
<th>Mag.</th>
<th>Place</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<p class="table-caption">
Events of the last <span id="events-timespan">180</span> days with magnitude <span id="events-minmag">1.2</span> or larger in the area of the map and special events in adjacents regions. Download as <a id="events-csv-link" href="link" download="events.csv">CSV file</a>.
</p>
<p class="table-caption">
<span id="events-type">Symbols:</span>
</p>
<p class="table-caption">
Reverse Geolocation courtesy of <a href="http://photon.komoot.io/" target="_blank">Photon by Komoot</a>
</p>
</div>
<!-- Stations -->
<div class="tab" id="stationstab">
<div class="pager stationspager" id="stationspager">
<img src="external/first.png" class="stationsfirst" alt="First" />
<img src="external/prev.png" class="stationsprev" alt="Prev" />
<span class="stationspagedisplay"></span>
<img src="external/next.png" class="stationsnext" alt="Next" />
<img src="external/last.png" class="stationslast" alt="Last" />
<select class="stationspagesize" title="Select page size">
<option value="5">5</option>
<option value="10">10</option>
<option value="15">15</option>
<option value="20">20</option>
<option value="25">25</option>
<option value="30">30</option>
<option value="35">35</option>
</select>
<select class="stationsgotoPage" title="Select page number"></select>
</div>
<table class="tablesorter" id="stationstable">
<colgroup>
<col width="77" />
<col/>
<col width="100" align="char" char="." />
<col width="100" align="char" char="." />
</colgroup>
<thead>
<tr>
<th>Network</th>
<th>Station</th>
<th>Latitude [°]</th>
<th>Longitude [°]</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<p class="table-caption">Download as <a id="stations-csv-link" href="link" download="stations.csv">CSV file</a>.</p>
</div>
<!-- More -->
<div class="tab more_de" id="moretab">
<p>Loading text ...</p>
</div>
<!-- Info -->
<div class="tab" id="infotab">
<div id="infoaccordion">
<h3 class="aheader">Navigation / Links</h3>
<div class="info_de"><p>Loading text ...</p></div>
<h3 class="aheader">Copyright / Licence</h3>
<div class="copyright_de"><p>Loading text ...</p></div>
<h3 class="aheader">Imprint</h3>
<div class="imprint_de"><p>Loading text ...</p></div>
</div>
</div>
</div>
<!-- Logo -->
<div class="rublogo"><a href="http://www.gmg.ruhr-uni-bochum.de/en/seisobs"><img class="rublogo" src="logo_RUB_155x30.png" alt="Ruhr-University Bochum" title="Ruhr-University Bochum" border="0"/></a></div>
<!-- Map -->
<div id="map" class="map"></div>
<div id="spinner" class="spinner" style="display:none;"><img id="img-spinner" src="spinner.gif" alt="Loading"/><br />Loading ...</div>
</body>
</html>

View File

@ -1,22 +0,0 @@
<div class="accordioncontent">
<h4>Navigation zu den Internetseiten</h4>
<ul>
<li>des <a class="intern" href="http://www.gmg.ruhr-uni-bochum.de/geophysik/seisobs">Seismologisches Observatorium</a><br /> der Ruhr-Universität Bochum</li>
<li>der <a class="intern" href="http://www.gmg.ruhr-uni-bochum.de/geophysik/seismology">Arbeitsgruppe Seismologie</a></li>
<li>des <a class="intern" href="http://www.gmg.ruhr-uni-bochum.de">Instituts für Geologie, Mineralogie und Geophysik</a></li>
<li>der <a class="intern" href="http://www.rub.de">Ruhr-Universität Bochum</a></li>
</ul>
<h4>Informationen zu Erdbeben</h4>
<ul>
<li>in <a class="extern" target="_blank" href="http://www.gd.nrw.de/a_beben.php">NRW</a> (<a class="extern" target="_blank" href="http://www.gd.nrw.de">Geologischer Dienst NRW</a>)</li>
<li>in <a class="extern" target="_blank" href="http://www.bgr.bund.de/DE/Themen/Erdbeben-Gefaehrdungsanalysen/Seismologie/Seismologie/Seis-Online/Liste_D_1Jahr/li_d_1jahr_node.html">Deutschland</a> (<a class="extern" target="_blank" href="http://www.bgr.bund.de">BGR Hannover</a>)</li>
<li>in <a class="extern" target="_blank" href="http://www.emsc-csem.org">Europa / Mittelmeerraum</a> (<a class="extern" target="_blank" href="http://www.emsc-csem.org">EMSC</a>)</li>
<li><a class="extern" target="_blank" href="http://geofon.gfz-potsdam.de/eqinfo/seismon/globmon.php">weltweit</a> (<a class="extern" target="_blank" href="http://geofon.gfz-potsdam.de">GEOFON, GFZ Potsdam</a>)</li>
<li><a class="extern" target="_blank" href="http://earthquake.usgs.gov/earthquakes/map/">weltweit</a> (<a class="extern" target="_blank" href="http://earthquake.usgs.gov/">USGS</a>)</li>
</ul>
<h4>Informationen zum Steinkohlenabbau in NRW</h4>
<ul>
<li>Homepage der <a class="extern" target="_blank" href="http://www.rag.de">RAG</a></li>
<li><a class="extern" target="_blank" href="http://www.bid.rag.de">Bürgerinformationssystem</a> der RAG</li>
</ul>
</div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

View File

@ -1,102 +0,0 @@
<style>
body {
padding: 0;
margin: 0;
}
html, body, #map {
z-index: 1;
position: absolute;
top: 0;
left: 0;
margin: 0;
width: 100%;
height: 100%;
font-family: sans-serif;
}
div.noscript {
z-index: 20000;
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 200%;
background: rgb(255, 255, 255);
}
div.noscriptcontent {
z-index: 20010;
margin: 45px;
font-size: small;
}
div.info {
z-index: 10000;
position: absolute;
left: 10px;
top: 14px;
padding: 4px;
width: 435px;
font-size: small;
font: sans-serif;
background: rgb(255, 255, 255);
background: rgba(255, 255, 255, 0.95);
border-radius: 4px;
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
overflow: auto;
}
div.tab {
z-index: 10010;
width: 400px;
padding: 0px;
float: left;
font-size: small;
font: sans-serif;
background: rgb(255, 255, 255);
background: rgba(25, 255, 255, 0.95);
}
div.accordioncontent {
z-index: 10010;
margin: 0px!important;
padding: 5px!important;
font: sans-serif;
}
div.rublogo {
z-index: 10000;
position: absolute;
top: 10px;
right: 46px;
height: 33px;
padding: 10px;
width: 155px;
font-size: x-small;
font: sans-serif;
color: #003560;
background: rgb(255, 255, 255);
background: rgba(255, 255, 255, 0.95);
border-radius: 4px;
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
}
a.map-link {
float: right;
}
li.infotab {
float: right!important;
}
td.ar {
text-align: right;
}
p.table-caption {
font-size: smaller;
}
div.spinner {
position: fixed;
top: 50%;
left: 50%;
margin-left: -64px; /* half width of the spinner gif */
margin-top: -8px; /* half height of the spinner gif */
text-align:center;
z-index: 19000;
overflow: auto;
width: 128px; /* width of the spinner gif */
height: 40px; /*hight of the spinner gif +2px to fix IE8 issue */
}
</style>

View File

@ -1,221 +0,0 @@
/**********************************************************************
* map.js *
* script for map specific functions and setup *
**********************************************************************/
/* License
Copyright 2014-2021 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 https://www.gnu.org/licenses/.
Version v1.3 (2023-04-17)
*/
/* add station marker */
function addStationMarker(id, lat, lng, station) {
var marker = L.triangleMarker(L.latLng(lat, lng),
{
gradient: true,
fillColor: config['station']['markerColor'],
fillOpacity: config['station']['markerOpacity'],
color: config['station']['markerColor'],
weight: 1,
opacity: 1,
radius: config['station']['markerSize'][id] || config['station']['markerSize']['defaultSize'],
className: id+' stationMarker',
});
marker.bindTooltip('Station '+station);
stationLayer.addLayer(marker);
stationTable[id] = marker;
};
/* add event marker */
function addEventMarker(id, lat, lng, mag, type) {
if ( eventTable[id] ) {
return eventTable[id];
} else {
var markerOptions = {
gradient: true,
dropShadow: false,
fillColor: config['event']['markerColor'],
fillOpacity: config['event']['markerOpacity'],
color: config['event']['markerColor'],
weight: 0,
opacity: 1,
className: id+' eventMarker',
radius: mag2radius(mag)
};
var marker;
switch ( type ) {
case 'earthquake':
marker = L.starMarker(L.latLng(lat, lng), markerOptions);
break;
case 'nuclear explosion':
markerOptions['numberOfSides'] = 4;
markerOptions['radius'] = 2.0*markerOptions['radius'];
markerOptions['innerRadius'] = 0.3*markerOptions['radius'];
marker = L.regularPolygonMarker(L.latLng(lat, lng), markerOptions);
break;
case 'explosion':
markerOptions['numberOfSides'] = 6;
markerOptions['radius'] = 2.0*markerOptions['radius'];
markerOptions['innerRadius'] = 0.3*markerOptions['radius'];
marker = L.regularPolygonMarker(L.latLng(lat, lng), markerOptions);
break;
case 'quarry blast':
case 'controlled explosion':
markerOptions['numberOfPoints'] = 7;
markerOptions['innerRadius'] = 0.3*markerOptions['radius'];
marker = L.starMarker(L.latLng(lat, lng), markerOptions);
break;
default:
marker = L.circleMarker(L.latLng(lat, lng), markerOptions);
};
eventLayer.addLayer(marker);
eventTable[id] = marker;
return marker;
};
};
/* handle to show events on map */
function initMapLink() {
$("#eventstable > tbody > tr > td > a.map-link").off('click');
$("#eventstable > tbody > tr > td > a.map-link").on('click' , function(){
var highlightStyle = {
color: config['event']['markerColorH'],
fillColor: config['event']['markerColorH'],
fillOpacity: 1,
className: $(this).attr('eventid')
}
var normalStyle = {
fillColor: config['event']['markerColor'],
fillOpacity: config['event']['markerOpacity'],
color: config['event']['markerColor']
};
// mark currently selected link and remove class selected from all other links
// set everything to normal state
$(this).addClass('selected-now');
$("#eventstable > tbody > tr:not(.filtered) > td > a.map-link:not(.selected-now)").each(function(){
$(this).removeClass('selected');
$(this).text('Karte');
eventTable[$(this).attr('eventid')].setStyle(normalStyle);
});
// switch event of first row to normalStyle if it is not the selected one
( $(this).hasClass('first') ) ? null : eventTable[$("#eventstable > tbody > tr:not(.filtered)").first().find("a.map-link").attr("eventid")].setStyle(normalStyle);
$(this).each(function(){
$(this).removeClass('selected-now');
// selected -> unselected
if ( $(this).hasClass('selected') ) {
$(this).removeClass('selected');
$(this).text('Karte');
map.setView(config['map']['centerDefault'], config['map']['zoomDefault']);
eventTable[$(this).attr('eventid')].setStyle(normalStyle);
highlightFirstEvent();
// unselected -> selected
} else {
$(this).addClass('selected');
$(this).text('im Fokus (rot)');
map.setView(eventTable[$(this).attr('eventid')].getLatLng(), config['map']['zoomFocus']);
eventTable[$(this).attr('eventid')].setStyle(highlightStyle)
};
});
return false;
});
};
/**********************************************************************
* document ready *
**********************************************************************/
$(document).ready(function() {
map = L.map('map', {
center: config['map']['centerDefault'],
zoom: config['map']['zoomDefault'],
zoomControl: false,
worldCopyJump: true
});
// change baselayer if mapquest is not requested
switch ( config['map']['baselayer'] ) {
case 'esrigray': // add ESRI Grayscale World Map (neither city nor road names)
L.tileLayer.provider('Esri.WorldGrayCanvas').addTo(map);
break;
case 'aerial': // add ESRI WordImagery tile layer
L.tileLayer.provider('Esri.WorldImagery').addTo(map);
break;
case 'opentopo': // add OpenTopoMap tile layer
L.tileLayer.provider('OpenTopoMap').addTo(map);
break;
case 'mapnik': // add OpenStreetMap.Mapnik tile layer
L.tileLayer.provider('OpenStreetMap.Mapnik').addTo(map);
break;
case 'topplus': // add TopPlus tile layer (https://gdz.bkg.bund.de/index.php/default/webdienste/topplus-produkte/wmts-topplusopen-wmts-topplus-open.html)
L.tileLayer('https://sgx.geodatenzentrum.de/wmts_topplus_open/tile/1.0.0/web/default/WEBMERCATOR/{z}/{y}/{x}.png',
{attribution: '&copy; Bundesamt für Kartographie und Geodäsie ('+jahr+'), Datenquellen: <a href="http://sg.geodatenzentrum.de/web_public/Datenquellen_TopPlus_Open.pdf">Geodatenzentrum</a>'}).addTo(map);
break;
case 'mapquest':
MQ.mapLayer().addTo(map);
break;
default: // use OpenStreetMap.DE as default
L.tileLayer.provider('OpenStreetMap.DE').addTo(map);
};
// add controls
new L.Control.Zoom({ position: 'topright' }).addTo(map);
new L.control.scale({position: 'bottomright', imperial: false}).addTo(map);
// create station and event layer
// stationLayer = L.geoJson().addTo(map);
stationLayer = new L.MarkerGroup().addTo(map);
eventLayer = new L.MarkerGroup().addTo(map);
// load events
ajaxLoadEvents('', '', '', 'data/events.xml');
ajaxLoadEvents();
specialEvents.map(function(id) {
ajaxLoadEvents('', '', id)
});
toggleFilteredMarkers();
// bind popupopen event
map.on('popupopen', function() {
// convert date/time to localtime
$("div.leaflet-popup span.utctime").each(function(){$(this).addClass("localtime").removeClass("utctime");$.localtime.formatObject($(this), "dd.MM.yyyy - HH:mm")});
openMarkerID = $("div.leaflet-popup h3").attr("eventid");
if ( openMarkerID ) {
// update city in popup
$("div.leaflet-popup h3").text(geolocationTable[openMarkerID]);
// highlight event in table and show details
// highlightEvent(eventid);
$('#eventstable > tbody > tr > td > a.toggle').each(function() {
if ( $(this).attr('eventid') == openMarkerID ) {
$(this)[0].click();
};
});
};
});
map.on('popupclose', function() {
$('#eventstable > tbody > tr > td > a.toggle').each(function() {
if ( $(this).attr('eventid') == openMarkerID ) {
$(this)[0].click();
};
});
});
// print icon
L.control.browserPrint({
title: 'print map',
position: 'topright',
}).addTo(map);
});

View File

@ -1,221 +0,0 @@
/**********************************************************************
* map.js.en *
* script for map specific functions and setup *
**********************************************************************/
/* License
Copyright 2014-2021 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 https://www.gnu.org/licenses/.
Version v1.3 (2023-04-17)
*/
/* add station marker */
function addStationMarker(id, lat, lng, station) {
var marker = L.triangleMarker(L.latLng(lat, lng),
{
gradient: true,
fillColor: config['station']['markerColor'],
fillOpacity: config['station']['markerOpacity'],
color: config['station']['markerColor'],
weight: 1,
opacity: 1,
radius: config['station']['markerSize'][id] || config['station']['markerSize']['defaultSize'],
className: id+' stationMarker',
});
marker.bindTooltip('Station '+station);
stationLayer.addLayer(marker);
stationTable[id] = marker;
};
/* add event marker */
function addEventMarker(id, lat, lng, mag, type) {
if ( eventTable[id] ) {
return eventTable[id];
} else {
var markerOptions = {
gradient: true,
dropShadow: false,
fillColor: config['event']['markerColor'],
fillOpacity: config['event']['markerOpacity'],
color: config['event']['markerColor'],
weight: 0,
opacity: 1,
className: id+' eventMarker',
radius: mag2radius(mag)
};
var marker;
switch ( type ) {
case 'earthquake':
marker = L.starMarker(L.latLng(lat, lng), markerOptions);
break;
case 'nuclear explosion':
markerOptions['numberOfSides'] = 4;
markerOptions['radius'] = 2.0*markerOptions['radius'];
markerOptions['innerRadius'] = 0.3*markerOptions['radius'];
marker = L.regularPolygonMarker(L.latLng(lat, lng), markerOptions);
break;
case 'explosion':
markerOptions['numberOfSides'] = 6;
markerOptions['radius'] = 2.0*markerOptions['radius'];
markerOptions['innerRadius'] = 0.3*markerOptions['radius'];
marker = L.regularPolygonMarker(L.latLng(lat, lng), markerOptions);
break;
case 'quarry blast':
case 'controlled explosion':
markerOptions['numberOfPoints'] = 7;
markerOptions['innerRadius'] = 0.3*markerOptions['radius'];
marker = L.starMarker(L.latLng(lat, lng), markerOptions);
break;
default:
marker = L.circleMarker(L.latLng(lat, lng), markerOptions);
};
eventLayer.addLayer(marker);
eventTable[id] = marker;
return marker;
};
};
/* handle to show events on map */
function initMapLink() {
$("#eventstable > tbody > tr > td > a.map-link").off('click');
$("#eventstable > tbody > tr > td > a.map-link").on('click' , function(){
var highlightStyle = {
color: config['event']['markerColorH'],
fillColor: config['event']['markerColorH'],
fillOpacity: 1,
className: $(this).attr('eventid')
}
var normalStyle = {
fillColor: config['event']['markerColor'],
fillOpacity: config['event']['markerOpacity'],
color: config['event']['markerColor']
};
// mark currently selected link and remove class selected from all other links
// set everything to normal state
$(this).addClass('selected-now');
$("#eventstable > tbody > tr:not(.filtered) > td > a.map-link:not(.selected-now)").each(function(){
$(this).removeClass('selected');
$(this).text('Karte');
eventTable[$(this).attr('eventid')].setStyle(normalStyle);
});
// switch event of first row to normalStyle if it is not the selected one
( $(this).hasClass('first') ) ? null : eventTable[$("#eventstable > tbody > tr:not(.filtered)").first().find("a.map-link").attr("eventid")].setStyle(normalStyle);
$(this).each(function(){
$(this).removeClass('selected-now');
// selected -> unselected
if ( $(this).hasClass('selected') ) {
$(this).removeClass('selected');
$(this).text('Karte');
map.setView(config['map']['centerDefault'], config['map']['zoomDefault']);
eventTable[$(this).attr('eventid')].setStyle(normalStyle);
highlightFirstEvent();
// unselected -> selected
} else {
$(this).addClass('selected');
$(this).text('at focus (red)');
map.setView(eventTable[$(this).attr('eventid')].getLatLng(), config['map']['zoomFocus']);
eventTable[$(this).attr('eventid')].setStyle(highlightStyle)
};
});
return false;
});
};
/**********************************************************************
* document ready *
**********************************************************************/
$(document).ready(function() {
map = L.map('map', {
center: config['map']['centerDefault'],
zoom: config['map']['zoomDefault'],
zoomControl: false,
worldCopyJump: true
});
// change baselayer if mapquest is not requested
switch ( config['map']['baselayer'] ) {
case 'esrigray': // add ESRI Grayscale World Map (neither city nor road names)
L.tileLayer.provider('Esri.WorldGrayCanvas').addTo(map);
break;
case 'aerial': // add ESRI WordImagery tile layer
L.tileLayer.provider('Esri.WorldImagery').addTo(map);
break;
case 'opentopo': // add OpenTopoMap tile layer
L.tileLayer.provider('OpenTopoMap').addTo(map);
break;
case 'mapnik': // add OpenStreetMap.Mapnik tile layer
L.tileLayer.provider('OpenStreetMap.Mapnik').addTo(map);
break;
case 'topplus': // add TopPlus tile layer (https://gdz.bkg.bund.de/index.php/default/webdienste/topplus-produkte/wmts-topplusopen-wmts-topplus-open.html)
L.tileLayer('https://sgx.geodatenzentrum.de/wmts_topplus_open/tile/1.0.0/web/default/WEBMERCATOR/{z}/{y}/{x}.png',
{attribution: '&copy; Federal Agency for Cartography and Geodesy ('+jahr+'), Datasource: <a href="http://sg.geodatenzentrum.de/web_public/Datenquellen_TopPlus_Open.pdf">Geodatenzentrum</a>'}).addTo(map);
break;
case 'mapquest':
MQ.mapLayer().addTo(map);
break;
default: // use OpenStreetMap.DE as default
L.tileLayer.provider('OpenStreetMap.DE').addTo(map);
};
// add controls
new L.Control.Zoom({ position: 'topright' }).addTo(map);
new L.control.scale({position: 'bottomright', imperial: false}).addTo(map);
// create station and event layer
// stationLayer = L.geoJson().addTo(map);
stationLayer = new L.MarkerGroup().addTo(map);
eventLayer = new L.MarkerGroup().addTo(map);
// load events
ajaxLoadEvents('', '', '', 'data/events.xml');
ajaxLoadEvents();
specialEvents.map(function(id) {
ajaxLoadEvents('', '', id)
});
toggleFilteredMarkers();
// bind popupopen event
map.on('popupopen', function() {
// convert date/time to localtime
$("div.leaflet-popup span.utctime").each(function(){$(this).addClass("localtime").removeClass("utctime");$.localtime.formatObject($(this), "dd.MM.yyyy - HH:mm")});
openMarkerID = $("div.leaflet-popup h3").attr("eventid");
if ( openMarkerID ) {
// update city in popup
$("div.leaflet-popup h3").text(geolocationTable[openMarkerID]);
// highlight event in table and show details
// highlightEvent(eventid);
$('#eventstable > tbody > tr > td > a.toggle').each(function() {
if ( $(this).attr('eventid') == openMarkerID ) {
$(this)[0].click();
};
});
};
});
map.on('popupclose', function() {
$('#eventstable > tbody > tr > td > a.toggle').each(function() {
if ( $(this).attr('eventid') == openMarkerID ) {
$(this)[0].click();
};
});
});
// print icon
L.control.browserPrint({
title: 'print map',
position: 'topright',
}).addTo(map);
});

View File

@ -1,251 +0,0 @@
/**********************************************************************
* misc.js *
* script for unspecific functions and setup *
**********************************************************************/
/* License
Copyright 2014-2023 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/.
Version v1.3 (2023-04-17)
*/
/* calculate marker radius from magnitude
* both formulas have equal radii at mag=1.2 */
function mag2radius(mag) {
return 3*mag; // radius proportional to magnitude
// return 8.104*Math.pow(30,mag) // radius proportional to energy
};
/* set height of eventlist div */
function setInfoHeight() {
var height = $('div.map').height() - 36;
$('div.info').height(height);
};
/* get region and regionID of a location */
function getLocation(lat, lng) {
var region = false;
var regionID;
var regions = [
['Monschau', 'Schleiden', 'Bad Münstereifel', 'Rheinland-Pfalz', 'Rheinland-Pfalz', 'Rheinland-Pfalz', 'Hessen', 'Hessen', 'Hessen', 'Hessen'],
['Aachen', 'Zülpich', 'Euskirchen', 'Bonn', 'Rheinland-Pfalz', 'Rheinland-Pfalz', 'Hessen', 'Hessen', 'Hessen', 'Hessen'],
['Geilenkirchen', 'Düren', 'Köln', 'Köln-Mülheim', 'Waldbröl', 'Freudenberg', 'Siegen', 'Hessen', 'Hessen', 'Hessen'],
['Heinsberg', 'Mönchengladbach', 'Neuss', 'Solingen', 'Gummersbach', 'Olpe', 'Schmallenberg', 'Bad Berleburg', 'Hessen', 'Hessen'],
['Nettetal', 'Krefeld', 'Düsseldorf', 'Wuppertal', 'Hagen', 'Iserlohn', 'Arnsberg', 'Brilon', 'Hessen', 'Hessen'],
['Geldern', 'Moers', 'Duisburg', 'Essen', 'Dortmund', 'Unna', 'Soest', 'Büren', 'Marsberg', 'Warburg'],
['Kleve', 'Wesel', 'Dorsten', 'Recklinghausen', 'Lünen', 'Hamm/Westfalen', 'Beckum', 'Lippstadt', 'Paderborn', 'Bad Driburg'],
['Emmerich am Rhein', 'Bocholt', 'Borken', 'Coesfeld', 'Münster', 'Warendorf', 'Rheda-Wiedenbrück', 'Gütersloh', 'Detmold', 'Bad Pyrmont'],
['The Netherlands', 'The Netherlands', 'Vreden', 'Ahaus', 'Steinfurt', 'Lengerich', 'Bad Ilburg', 'Bielefeld', 'Herford', 'Niedersachsen'],
['The Netherlands', 'The Netherlands', 'The Netherlands', 'Niedersachsen', 'Rheine', 'Ibbenbüren', 'Niedersachsen', 'Lübbecke', 'Minden', 'Niedersachsen']
];
if ( lat >= 50.4 && lat < 52.4 && lng >= 6.0 && lng < 9.333333 ) {
var latIndex = Math.floor((lat-50.4)*5); // 5 tiles per degree
var lngIndex = Math.floor((lng-6.0)*3); // 3 tiles per degree
region = regions[latIndex][lngIndex];
};
if ( region != 'The Netherlands' ) {
regionID = 5500-latIndex*200+lngIndex*2+2;
};
if ( lat >= 50.9 && lat < 51.1 && lng >= 5.666666 && lng < 6.0 ) {
region = 'Selfkant';
regionID = 5000;
};
return [ region, regionID ];
};
/* window resize */
$( window ).on('resize', function() { setInfoHeight(); });
/* parseQueryString */
function parseQueryString() {
var query = (window.location.search || '?').substr(1),
map = {};
query.replace(/([^&=]+)=?([^&]*)(?:&+|$)/g, function(match, key, value) {
key.toLowerCase();
(map[key] = map[key] || []).push(value);
});
return map;
}
/* create global vars */
var jahr = new Date().getFullYear();
var map;
var openMarkerID;
var eventTable = {};
var eventDetails = {};
var stationTable = {};
var config = {
ajax: {
timeout: 20000, // 20 seconds
eventURL: 'https://fdsnws.geophysik.ruhr-uni-bochum.de/fdsnws/event/1/query',
dlsvURL: 'dlsv',
mseedURL: 'https://fdsnws.geophysik.ruhr-uni-bochum.de/fdsnws/dataselect/1/query',
stationURL: 'https://fdsnws.geophysik.ruhr-uni-bochum.de/fdsnws/station/1/query',
nominatimURL: 'https://photon.komoot.io/reverse',
timespan: 400,
},
event: {
evaluationBlacklist: ['automatic', 'preliminary', 'rejected'],
markerOpacity: 0.4,
markerColor: 'blue',
markerColorH: 'red',
minMag: 0.7,
minMagDelta: 0.1,
typeWhitelist: ['earthquake', 'induced or triggered event', 'controlled explosion'],
// typeWhitelist: ['earthquake', 'induced or triggered event', 'controlled explosion', 'nuclear explosion'],
// typeWhitelist: ['earthquake', 'induced or triggered event'],
},
map: {
zoomDefault: 9,
zoomFocus: 12,
centerDefault: [51.85, 7.0],
timespan: 180,
latlngDelta: 0.1,
baselayer: 'OpenStreetMap.DE',
},
station: {
markerColor: 'darkgreen',
markerOpacity: 1,
markerSize: {
defaultSize: 8,
GE_IBBN: 10,
GR_BUG: 10,
GR_KAST: 10,
NL_HGN: 3,
NL_OPLO: 3,
NL_VKB: 3,
NL_WIT: 3,
NL_WTSB: 3,
},
networkBlacklist: ['NL', 'X5', '1A', 'AM'],
stationBlacklist: ['RN_WEA2', 'RN_ACN', 'RN_BHE', 'RN_ENT', 'RN_GSH', 'RN_HES', 'RN_JCKS', 'RN_LOH',
'RN_OLF', 'RN_PLH', 'RN_RWB', 'RN_SOR', 'RN_TDN', 'RN_WBS',
'RN_HAM1', 'RN_HAM2', 'RN_HAM3', 'RN_HAM4', 'RN_HAM5', 'RN_HAM6', 'RN_HAM7', 'RN_HAM8', 'RN_HAM9',
'RN_HAM10', 'RN_HAM11', 'RN_HAM12', 'RN_HAM13', 'RN_HAM14', 'RN_HAM15', 'RN_HAM16', 'RN_HAM17'],
},
tab: {
active: 0,
disabled: [2],
max: 4,
},
};
var networkURL = {
GE: 'http://dx.doi.org/10.14470/TR560404',
GR: 'http://www.bgr.bund.de/DE/Themen/Erdbeben-Gefaehrdungsanalysen/Seismologie/Seismologie/Seismometer_Stationen/Stationsnetze/d_stationsnetz_node.html',
NH: 'http://www.gd.nrw.de/gg_le.htm',
NL: 'http://www.knmi.nl/seismologie/seismisch_network_knmi3.html',
RN: 'https://doi.org/10.7914/SN/RN',
YD: 'https://doi.org/10.7914/SN/YD_2020',
};
var networkText = {
GE: '<a href="'+networkURL['GE']+'" target="_blank">GEOFON Seismic Network</a> - Deutsches GeoForschungsZentrum GFZ',
GR: '<a href="'+networkURL['GR']+'" target="_blank">German Regional Seismic Network</a>, BGR Hannover',
NH: '<a href="'+networkURL['NH']+'" target="_blank">Geologischer Dienst NRW</a>, Krefeld',
NL: '<a href="'+networkURL['NL']+'" target="_blank">Netherlands Seismic Network</a>, The Netherlands',
RN: '<a href="'+networkURL['RN']+'" target="_blank">RuhrNet - Ruhr-University Bochum, Germany</a>',
YD: '<a href="'+networkURL['YD']+'" target="_blank">FloodRisk Seismic Network</a>',
};
var bochumStation = ['BUG', 'IBBN', 'KERA', 'KARP'];
// FIX: firefox has no console
if (typeof console == "undefined") var console = { log: function() {} };
/**********************************************************************
* document ready *
**********************************************************************/
$(document).ready(function() {
// parse query string
var parameters = parseQueryString();
if ( parameters['baselayer']) {
config['map']['baselayer'] = parameters['baselayer'][0];
};
if ( parameters['basemap'] ) {
config['map']['baselayer'] = parameters['basemap'][0];
};
if ( Number(parameters['lat']) && Number(parameters['lon']) ) {
config['map']['centerDefault'] = [Number(parameters['lat']), Number(parameters['lon'])];
};
if ( Number(parameters['minmag']) ) {
config['event']['minMag'] = Number(parameters['minmag']);
};
if ( parameters['eventcolor'] ) {
config['event']['markerColor'] = parameters['eventcolor'];
};
if ( parameters['eventcolorh'] ) {
config['event']['markerColorH'] = parameters['eventcolorh'];
};
if ( parameters['stationcolor'] ) {
config['station']['markerColor'] = parameters['stationcolor'];
};
if ( Number(parameters['timespan']) ) {
config['map']['timespan'] = Number(parameters['timespan']);
};
if ( Number(parameters['tab']) ) {
if ( Number(parameters['tab']) < config['tab']['max'] ) {
config['tab']['active'] = Number(parameters['tab']);
};
};
if ( Number(parameters['zoom']) ) {
config['map']['zoomDefault'] = Number(parameters['zoom']);
config['map']['zoomFocus'] = Number(parameters['zoom']+3);
};
// AJAX setup
$.ajaxSetup({timeout: config['ajax']['timeout']});
// adjust height of infocontainer
setInfoHeight();
// create tabs
$('#tabs').tabs({
active: config['tab']['active'],
disabled: config['tab']['disabled'],
activate: function( event, ui ) { ui['newPanel'].find('table').trigger("update", [true]); },
});
// create accordions
$( '#infoaccordion' ).accordion({
active: 0,
header: 'h3.aheader',
heightStyle: 'content',
animate: 200,
});
// spinner
$(document).on("ajaxSend", function() {
$("#spinner").show();
}).on("ajaxStop", function() {
$("#spinner").hide();
});
// load more tab content
$.get("more_de.md", function( data ) {
var converter = new showdown.Converter();
$('.more_de').html(converter.makeHtml(data));
});
$.get("more_en.md", function( data ) {
var converter = new showdown.Converter();
$('.more_en').html(converter.makeHtml(data));
});
// load info tab content
$.get("info.inc.de", function( data ) {
$('.info_de, .info_en').html(data);
});
$.get("copyright.inc.de", function( data ) {
$('.copyright_de, .copyright_en').html(data);
});
$.get("impressum.inc.de", function( data ) {
$('.imprint_de, .imprint_en').html(data);
});
});

View File

@ -1,9 +0,0 @@
# Seismologisches Observatorium
## Stationsnetz
Das seismologische Observatorium der Ruhr-Universität Bochum betreibt mehrere seismologische Stationen im Ruhrgebiet, im Raum Ibbenbüren und im Alpenvorland. Zwei breitbandige Stationen (BUG und IBBN) sind gleichzeitig Bestandteil des Deutschen Seismologischen Regionalnetzes (GRSN). Sie befinden sich in der Nähe der Ruhr-Universität in einem stillgelegten Stollen der Zeche Klosterbusch bzw. bei Ibbenbüren.
## Seismologische Netzwerke
### RuhrNet (RN)
### FloodRisk (YD)
### AlpArray (Z3)

View File

@ -1,9 +0,0 @@
# Seismological Observatory
## Station Network
The seismological observatory of the Ruhr-University Bochum (Germany) maintains several seismolocical stations in the Ruhr area, around Ibbenbueren and in the foreland of the Alps. Two broadband stations (BUG and IBBN) are also part of the German Regional Seismological Network (GRSN). These are located near the Ruhr-University in an abandoned coal mine and near the city of Ibbenbueren.
## Seismological Networks
### RuhrNet (RN)
### FloodRisk (YD)
### AlpArray (Z3)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -1,266 +0,0 @@
/**********************************************************************
* stations.js *
* script for station specific functions and setup *
**********************************************************************/
/* License
Copyright 2014-2021 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/.
Version v1.3 (2023-04-17)
*/
/* Load the stations using ajax */
function loadStations(station, 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);
};
if ( !station ) {
var request_data = {
endafter: sprintf("%d-%02d-%02d", stime.getFullYear(), stime.getMonth()+1, stime.getDate()),
startbefore: sprintf("%d-%02d-%02d", etime.getFullYear(), etime.getMonth()+1, etime.getDate()),
level: 'station',
minlat: S-config['map']['latlngDelta'],
maxlat: N+config['map']['latlngDelta'],
minlon: W-config['map']['latlngDelta'],
maxlon: E+config['map']['latlngDelta'],
};
} else {
var request_data = {
endafter: sprintf("%d-%02d-%02d", stime.getFullYear(), stime.getMonth()+1, stime.getDate()),
startbefore: sprintf("%d-%02d-%02d", etime.getFullYear(), etime.getMonth()+1, etime.getDate()),
level: 'channel',
station: station,
};
};
$.ajax({
type: "GET",
url: config['ajax']['stationURL'],
dataType: "xml",
data: request_data,
success: function (xml) {
$(xml).find('Network').each(function () {
var network = $(this).attr('code');
if ( $.inArray(network, config['station']['networkBlacklist'])<0 ) {
$(this).find('Station').each(function () {
var station = $(this).attr('code'),
lat = $(this).find('Latitude:first').text(),
lng = $(this).find('Longitude:first').text(),
stationID = network+'_'+station,
stationText = network+'.'+station;
if ( !stationTable[stationID] && $.inArray(stationID, config['station']['stationBlacklist']) <0 ) {
// general station info (1st line)
var row = sprintf('<tr><td><a href="#" class="toggle">%s</a></td><td><a href="#" class="toggle">%s</a></td><td class="ar">%7.4f</td><td class="ar">%7.4f</td></tr>' , network, station, Number(lat), Number(lng));
// setting up network details (2nd line)
row += sprintf('<tr class="tablesorter-childRow station-details"><td colspan="4">%s', networkText[network] || '');
row += ( $.inArray(station, bochumStation)+1 ) ? '<br /><em>Betreiber:</em> Ruhr-Universität Bochum</td></tr>' : '</td></tr>' ;
if ( network == 'RN' || network == 'Z3' || network == '1A' || network == 'YD' || $.inArray(station, bochumStation)+1 ) {
// setting up station details (3rd line)
row += '<tr class="tablesorter-childRow station-details"><td colspan="4">';
row += stationDetails(station, network, lat, lng, stationID, stationText, $(this));
row += '</td></tr>';
// setting up download links (4th line)
var URL, fdsnxmlURL, fdsnxmlRespURL, sc3mlURL, sc3mlRespURL, dlsvURL;
URL = sprintf('%s?network=%s&station=%s', config['ajax']['stationURL'], network, station);
fdsnxmlURL = URL + '&level=station&format=xml';
fdsnxmlRespURL = URL + '&level=response&format=xml';
sc3mlURL = URL + '&level=station&format=sc3ml';
sc3mlRespURL = URL + '&level=response&format=sc3ml';
dlsvFile = sprintf('%s_%s.dlsv', network.toUpperCase(), station.toUpperCase());
row += '<tr class="tablesorter-childRow station-download"><td colspan="4">'
+ sprintf('Download details: <a download="%s.xml" href="%s" target="_blank">FDSNxml</a> or <a download="%s.sc3" href="%s" target="_blank">SC3ml</a><br /> ', stationID, fdsnxmlURL, stationID, sc3mlURL)
+ sprintf('Response files: <a download="%s_response.xml" href="%s" target="_blank">FDSNxml</a>, <a download="%s_response.sc3" href="%s" target="_blank">SC3ml</a> ', stationID, fdsnxmlRespURL, stationID, sc3mlRespURL)
+ sprintf('or <a href="%s" download="%s" type="application/octet-stream">datalessSEED</a>', config['ajax']['dlsvURL'] + '/' + dlsvFile, dlsvFile.toLowerCase())
+ '</td></tr>';
}
else {
row += '<tr class="tablesorter-childRow station-details"><td colspan="4">Kontaktieren Sie den ';
row += ( networkURL[network.toUpperCase()] ) ? '<a href="'+networkURL[network.toUpperCase()]+'" target="_blank">Netzwerkkoordinator</a>' : 'Netzwerkkoordinator';
row += ' für weitere Details.</td></tr>';
};
$('#stationstable tbody').append(row);
addStationMarker(stationID, Number(lat), Number(lng), stationText.toUpperCase());
};
});
};
});
},
complete: function () {
initStationTable();
var sort = [[0,0],[1,0]];
$("#stationstable").trigger("update", [true]);
$("#stationstable").trigger("updateCache");
$("#stationstable").trigger("sorton", [sort]);
$("#stationstable > tbody > tr:even").addClass("odd");
$("#stationstable > tbody > tr:odd").addClass("even");
stationLayer.bringToFront();
},
error: function( jqxhr, textStatus, error ) {
var err = textStatus + ", " + error;
console.log( "Request Failed: " + err );
}
});
// create stations csv download link
var request_data = {
endafter: sprintf("%d-%02d-%02d", stime.getFullYear(), stime.getMonth()+1, stime.getDate()),
startbefore: sprintf("%d-%02d-%02d", etime.getFullYear(), etime.getMonth()+1, etime.getDate()),
level: 'station',
minlat: S-config['map']['latlngDelta'],
maxlat: N+config['map']['latlngDelta'],
minlon: W-config['map']['latlngDelta'],
maxlon: E+config['map']['latlngDelta'],
format: 'text',
};
$('#stations-csv-link').attr('href', config['ajax']['stationURL']+'?'+$.param(request_data));
};
/* format station Details */
function stationDetails(station, network, lat, lng, stationId, stationText, stationObject) {
var output;
var elevation = stationObject.find('Elevation:first').text();
var name = stationObject.find('Site > Name').text();
output = '<pre>'
+ name + '<br />'
+ 'Position: ' + lat + '°N ' + lng + '°E, Höhe: ' + elevation + ' m NN<br />';
stationObject.find('Channel').each(function() {
var code = $(this).attr('code');
var sensor = $(this).find('Sensor > Type').text().split(',')[0];
var sampleRate = $(this).find('SampleRate').text();
output += '<br />Kanal ' + code + ', Abtastrate ' + sampleRate + ' Hz, Sensor ' + sensor;
});
output += '</pre>';
return output;
};
/* initStationTable */
function initStationTable() {
// tablesorter for station list
$("#stationstable").tablesorter(
{
theme : 'blue',
cssChildRow: "tablesorter-childRow", // this is the default setting
widgets: ["uitheme", "zebra", "filter", "pager"], // initialize zebra and filter widgets, "scroller"
widgetOptions: {
// output default: '{page}/{totalPages}'
// possible variables: {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows}
pager_output: '# {startRow} - {endRow} ({totalRows}) | Seite {page} ({totalPages})',
// apply disabled classname to the pager arrows when the rows at either extreme is visible
pager_updateArrows: true,
// starting page of the pager (zero based index)
pager_startPage: 0,
// Number of visible rows
pager_size: 35,
// Save pager page & size if the storage script is loaded (requires $.tablesorter.storage in jquery.tablesorter.widgets.js)
pager_savePages: true,
// if true, the table will remain the same height no matter how many records are displayed. The space is made up by an empty
// table row set to a height to compensate; default is false
pager_fixedHeight: false,
// remove rows from the table to speed up the sort of large tables.
// setting this to false, only hides the non-visible rows; needed if you plan to add/remove rows with the pager enabled.
pager_removeRows: false,
// css class names of pager arrows
pager_css: {
container : 'stations-tablesorter-pager',
errorRow : 'stations-tablesorter-errorRow', // error information row (don't include period at beginning)
disabled : 'disabled' // class added to arrows @ extremes (i.e. prev/first arrows "disabled" on first page)
},
// jQuery pager selectors
pager_selectors: {
container : '.stationspager', // target the pager markup (wrapper)
first : '.stationsfirst', // go to first page arrow
prev : '.stationsprev', // previous page arrow
next : '.stationsnext', // next page arrow
last : '.stationslast', // go to last page arrow
goto : '.stationsgotoPage', // go to page selector - select dropdown that sets the current page
pageDisplay : '.stationspagedisplay', // location of where the "output" is displayed
pageSize : '.stationspagesize' // page size selector - select dropdown that sets the "size" option
},
filter_childRows : true,
filter_cssFilter : 'stations-tablesorter-filter',
filter_startsWith : false,
filter_ignoreCase : true,
scroller_height: $('div.map').height() - 250,
scroller_barWidth: 10,
scroller_jumpToHeader: false,
sortList: "[[0,0], [1,0]]",
resort: true,
showProcessing: true,
}
});
// hide child rows
$('#stationstable > tbody > tr.tablesorter-childRow > td').hide();
// update map after filtering
// $('#stationsstable').on('filterEnd', function(){
// toggleFilteredMarkers();
// });
};
/**********************************************************************
* document ready *
**********************************************************************/
$(document).ready(function() {
loadStations();
loadStations('A100A');
loadStations('A101B');
loadStations('A102A');
loadStations('A103A');
loadStations('A103B');
loadStations('A104A');
loadStations('A104B');
loadStations('A105A');
loadStations('A106B');
loadStations('A107C');
loadStations('A108A');
loadStations('A109A');
// loadStations('KERA');
// loadStations('KARP');
// show / hide station info
$('#stationstable').on('click', '.toggle' , function(){
// 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');
//highlightFirstEvent();
} else {
$(this).addClass('selected');
//toggleHighlightStation($(this).attr('stationid'));
};
});
return false;
});
});

View File

@ -1,266 +0,0 @@
/**********************************************************************
* stations.js.en *
* script for station specific functions and setup *
**********************************************************************/
/* License
Copyright 2014-2021 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/.
Version v1.3 (2023-04-17)
*/
/* Load the stations using ajax */
function loadStations(station, 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);
};
if ( !station ) {
var request_data = {
endafter: sprintf("%d-%02d-%02d", stime.getFullYear(), stime.getMonth()+1, stime.getDate()),
startbefore: sprintf("%d-%02d-%02d", etime.getFullYear(), etime.getMonth()+1, etime.getDate()),
level: 'station',
minlat: S-config['map']['latlngDelta'],
maxlat: N+config['map']['latlngDelta'],
minlon: W-config['map']['latlngDelta'],
maxlon: E+config['map']['latlngDelta'],
};
} else {
var request_data = {
endafter: sprintf("%d-%02d-%02d", stime.getFullYear(), stime.getMonth()+1, stime.getDate()),
startbefore: sprintf("%d-%02d-%02d", etime.getFullYear(), etime.getMonth()+1, etime.getDate()),
level: 'channel',
station: station,
};
};
$.ajax({
type: "GET",
url: config['ajax']['stationURL'],
dataType: "xml",
data: request_data,
success: function (xml) {
$(xml).find('Network').each(function () {
var network = $(this).attr('code');
if ( $.inArray(network, config['station']['networkBlacklist'])<0 ) {
$(this).find('Station').each(function () {
var station = $(this).attr('code'),
lat = $(this).find('Latitude:first').text(),
lng = $(this).find('Longitude:first').text(),
stationID = network+'_'+station,
stationText = network+'.'+station;
if ( !stationTable[stationID] && $.inArray(stationID, config['station']['stationBlacklist']) <0 ) {
// general station info (1st line)
var row = sprintf('<tr><td><a href="#" class="toggle">%s</a></td><td><a href="#" class="toggle">%s</a></td><td class="ar">%7.4f</td><td class="ar">%7.4f</td></tr>' , network, station, Number(lat), Number(lng));
// setting up network details (2nd line)
row += sprintf('<tr class="tablesorter-childRow station-details"><td colspan="4">%s', networkText[network] || '');
row += ( $.inArray(station, bochumStation)+1 ) ? '<br /><em>Operator:</em> Ruhr-University Bochum, Germany</td></tr>' : '</td></tr>' ;
if ( network == 'RN' || network == 'Z3' || network == '1A' || network == 'YD' || $.inArray(station, bochumStation)+1 ) {
// setting up station details (3rd line)
row += '<tr class="tablesorter-childRow station-details"><td colspan="4">';
row += stationDetails(station, network, lat, lng, stationID, stationText, $(this));
row += '</td></tr>';
// setting up download links (4th line)
var URL, fdsnxmlURL, fdsnxmlRespURL, sc3mlURL, sc3mlRespURL, dlsvURL;
URL = sprintf('%s?network=%s&station=%s', config['ajax']['stationURL'], network, station);
fdsnxmlURL = URL + '&level=station&format=xml';
fdsnxmlRespURL = URL + '&level=response&format=xml';
sc3mlURL = URL + '&level=station&format=sc3ml';
sc3mlRespURL = URL + '&level=response&format=sc3ml';
dlsvFile = sprintf('%s_%s.dlsv', network.toUpperCase(), station.toUpperCase());
row += '<tr class="tablesorter-childRow station-download"><td colspan="4">'
+ sprintf('Download details: <a download="%s.xml" href="%s" target="_blank">FDSNxml</a> or <a download="%s.sc3" href="%s" target="_blank">SC3ml</a><br /> ', stationID, fdsnxmlURL, stationID, sc3mlURL)
+ sprintf('Response files: <a download="%s_response.xml" href="%s" target="_blank">FDSNxml</a>, <a download="%s_response.sc3" href="%s" target="_blank">SC3ml</a> ', stationID, fdsnxmlRespURL, stationID, sc3mlRespURL)
+ sprintf('or <a href="%s" download="%s" type="application/octet-stream">datalessSEED</a>', config['ajax']['dlsvURL'] + '/' + dlsvFile, dlsvFile.toLowerCase())
+ '</td></tr>';
}
else {
row += '<tr class="tablesorter-childRow station-details"><td colspan="4">Kontaktieren Sie den ';
row += ( networkURL[network.toUpperCase()] ) ? '<a href="'+networkURL[network.toUpperCase()]+'" target="_blank">Netzwerkkoordinator</a>' : 'Netzwerkkoordinator';
row += ' für weitere Details.</td></tr>';
};
$('#stationstable tbody').append(row);
addStationMarker(stationID, Number(lat), Number(lng), stationText.toUpperCase());
};
});
};
});
},
complete: function () {
initStationTable();
var sort = [[0,0],[1,0]];
$("#stationstable").trigger("update", [true]);
$("#stationstable").trigger("updateCache");
$("#stationstable").trigger("sorton", [sort]);
$("#stationstable > tbody > tr:even").addClass("odd");
$("#stationstable > tbody > tr:odd").addClass("even");
stationLayer.bringToFront();
},
error: function( jqxhr, textStatus, error ) {
var err = textStatus + ", " + error;
console.log( "Request Failed: " + err );
}
});
// create stations csv download link
var request_data = {
endafter: sprintf("%d-%02d-%02d", stime.getFullYear(), stime.getMonth()+1, stime.getDate()),
startbefore: sprintf("%d-%02d-%02d", etime.getFullYear(), etime.getMonth()+1, etime.getDate()),
level: 'station',
minlat: S-config['map']['latlngDelta'],
maxlat: N+config['map']['latlngDelta'],
minlon: W-config['map']['latlngDelta'],
maxlon: E+config['map']['latlngDelta'],
format: 'text',
};
$('#stations-csv-link').attr('href', config['ajax']['stationURL']+'?'+$.param(request_data));
};
/* format station Details */
function stationDetails(station, network, lat, lng, stationId, stationText, stationObject) {
var output;
var elevation = stationObject.find('Elevation:first').text();
var name = stationObject.find('Site > Name').text();
output = '<pre>'
+ name + '<br />'
+ 'Position: ' + lat + '°N ' + lng + '°E, height: ' + elevation + ' m a.s.l.<br />';
stationObject.find('Channel').each(function() {
var code = $(this).attr('code');
var sensor = $(this).find('Sensor > Type').text().split(',')[0];
var sampleRate = $(this).find('SampleRate').text();
output += '<br />Channel ' + code + ', Samplingrate ' + sampleRate + ' Hz, Sensor ' + sensor;
});
output += '</pre>';
return output;
};
/* initStationTable */
function initStationTable() {
// tablesorter for station list
$("#stationstable").tablesorter(
{
theme : 'blue',
cssChildRow: "tablesorter-childRow", // this is the default setting
widgets: ["uitheme", "zebra", "filter", "pager"], // initialize zebra and filter widgets, "scroller"
widgetOptions: {
// output default: '{page}/{totalPages}'
// possible variables: {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows}
pager_output: '# {startRow} - {endRow} ({totalRows}) | page {page} ({totalPages})',
// apply disabled classname to the pager arrows when the rows at either extreme is visible
pager_updateArrows: true,
// starting page of the pager (zero based index)
pager_startPage: 0,
// Number of visible rows
pager_size: 35,
// Save pager page & size if the storage script is loaded (requires $.tablesorter.storage in jquery.tablesorter.widgets.js)
pager_savePages: true,
// if true, the table will remain the same height no matter how many records are displayed. The space is made up by an empty
// table row set to a height to compensate; default is false
pager_fixedHeight: false,
// remove rows from the table to speed up the sort of large tables.
// setting this to false, only hides the non-visible rows; needed if you plan to add/remove rows with the pager enabled.
pager_removeRows: false,
// css class names of pager arrows
pager_css: {
container : 'stations-tablesorter-pager',
errorRow : 'stations-tablesorter-errorRow', // error information row (don't include period at beginning)
disabled : 'disabled' // class added to arrows @ extremes (i.e. prev/first arrows "disabled" on first page)
},
// jQuery pager selectors
pager_selectors: {
container : '.stationspager', // target the pager markup (wrapper)
first : '.stationsfirst', // go to first page arrow
prev : '.stationsprev', // previous page arrow
next : '.stationsnext', // next page arrow
last : '.stationslast', // go to last page arrow
goto : '.stationsgotoPage', // go to page selector - select dropdown that sets the current page
pageDisplay : '.stationspagedisplay', // location of where the "output" is displayed
pageSize : '.stationspagesize' // page size selector - select dropdown that sets the "size" option
},
filter_childRows : true,
filter_cssFilter : 'stations-tablesorter-filter',
filter_startsWith : false,
filter_ignoreCase : true,
scroller_height: $('div.map').height() - 250,
scroller_barWidth: 10,
scroller_jumpToHeader: false,
sortList: "[[0,0], [1,0]]",
resort: true,
showProcessing: true,
}
});
// hide child rows
$('#stationstable > tbody > tr.tablesorter-childRow > td').hide();
// update map after filtering
// $('#stationsstable').on('filterEnd', function(){
// toggleFilteredMarkers();
// });
};
/**********************************************************************
* document ready *
**********************************************************************/
$(document).ready(function() {
loadStations();
loadStations('A100A');
loadStations('A101B');
loadStations('A102A');
loadStations('A103A');
loadStations('A103B');
loadStations('A104A');
loadStations('A104B');
loadStations('A105A');
loadStations('A106B');
loadStations('A107C');
loadStations('A108A');
loadStations('A109A');
// loadStations('KERA');
// loadStations('KARP');
// show / hide station info
$('#stationstable').on('click', '.toggle' , function(){
// 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');
//highlightFirstEvent();
} else {
$(this).addClass('selected');
//toggleHighlightStation($(this).attr('stationid'));
};
});
return false;
});
});