MediaWiki:Gadget-WetterGenerator.js: Unterschied zwischen den Versionen
Admin (Diskussion | Beiträge) Die Seite wurde neu angelegt: „/** * MediaWiki:Gadget-WetterGenerator.js (Ausbaustufe 2) * ===================================================================== * Formular zum Erstellen von Wetterwidget-Bausteinen für Gemeindeseiten * – jetzt zusätzlich mit: * * A) WIKIMAP-EXPORT: Ein Klick holt die aktuelle Stationsliste live von * GeoSphere und erzeugt fertige Einträge für WikiMap-Orte.json * (Kategorie "Wetterstation", einstellbarer Umkreis, leer = ganz *…“ |
Admin (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
||
| Zeile 1: | Zeile 1: | ||
/** | /** | ||
* MediaWiki:Gadget-WetterGenerator.js (Ausbaustufe | * MediaWiki:Gadget-WetterGenerator.js (Ausbaustufe 3) | ||
* ===================================================================== | * ===================================================================== | ||
* Formular zum Erstellen von Wetterwidget-Bausteinen für Gemeindeseiten | * Formular zum Erstellen von Wetterwidget-Bausteinen für Gemeindeseiten | ||
| Zeile 18: | Zeile 18: | ||
* einen Stationsmarker auf der WikiMap und folgt dem Link, steht | * einen Stationsmarker auf der WikiMap und folgt dem Link, steht | ||
* hier sofort der fertige {{Wetterwidget|...}}-Baustein bereit. | * hier sofort der fertige {{Wetterwidget|...}}-Baustein bereit. | ||
* | |||
* C) GEMEINDELEISTE: Das Formular gibt (abwählbar per Häkchen) vor dem | |||
* Wetterwidget-Baustein auch den Aufruf der [[Vorlage:Gemeindeleiste]] | |||
* aus – die Button-Zeile mit Wetter-, Radar-, Wolken-, Nachthimmel-, | |||
* Pollen-, Warnungs-, Website- und Wikipedia-Link. Die Dienst- | |||
* Adressen stecken in der Vorlage (eine Stelle für Änderungen); | |||
* das Formular liefert nur die Werte. Dafür gibt es drei neue | |||
* Eingabefelder (PLZ, Website, Wikipedia). Beim Karten-Rücksprung | |||
* (B) ist das Häkchen automatisch abgewählt, denn eine Station ist | |||
* keine Gemeinde. | |||
* | * | ||
* Datenquelle: GeoSphere Austria Dataset-API (Open Data, CC BY 4.0), | * Datenquelle: GeoSphere Austria Dataset-API (Open Data, CC BY 4.0), | ||
| Zeile 74: | Zeile 84: | ||
.attr( { type: 'text', placeholder: 'z. B. 15,8446' } ) | .attr( { type: 'text', placeholder: 'z. B. 15,8446' } ) | ||
.css( 'width', '10em' ); | .css( 'width', '10em' ); | ||
/* --- Zusatzfelder für die Gemeindeleiste (Button-Zeile) --- */ | |||
el.plz = $( '<input>' ) | |||
.attr( { type: 'text', placeholder: 'z. B. 2632' } ) | |||
.css( 'width', '6em' ) | |||
.on( 'input', aktualisiereBaustein ); | |||
el.website = $( '<input>' ) | |||
.attr( { type: 'text', | |||
placeholder: 'z. B. https://www.gemeinde-altendorf.at/' } ) | |||
.css( { width: '100%', 'max-width': '26em' } ) | |||
.on( 'input', aktualisiereBaustein ); | |||
el.wikipedia = $( '<input>' ) | |||
.attr( { type: 'text', | |||
placeholder: 'z. B. https://de.wikipedia.org/wiki/Altendorf_(Niederösterreich)' } ) | |||
.css( { width: '100%', 'max-width': '26em' } ) | |||
.on( 'input', aktualisiereBaustein ); | |||
el.mitLeiste = $( '<input>' ) | |||
.attr( { type: 'checkbox' } ) | |||
.prop( 'checked', true ) | |||
.on( 'change', aktualisiereBaustein ); | |||
el.suchen = $( '<button>' ) | el.suchen = $( '<button>' ) | ||
| Zeile 140: | Zeile 173: | ||
feld( 'Breitengrad (Dezimalgrad)', el.lat ), | feld( 'Breitengrad (Dezimalgrad)', el.lat ), | ||
feld( 'Längengrad (Dezimalgrad)', el.lon ), | feld( 'Längengrad (Dezimalgrad)', el.lon ), | ||
feld( 'PLZ (für den Wetterlink der Leiste)', el.plz ), | |||
feld( 'Gemeinde-Website (optional)', el.website ), | |||
feld( 'Wikipedia-Adresse (optional)', el.wikipedia ), | |||
$( '<label>' ) | |||
.css( { display: 'block', margin: '0.6em 0' } ) | |||
.append( el.mitLeiste, document.createTextNode( | |||
' Gemeindeleiste (Button-Zeile) mit ausgeben' ) ), | |||
$( '<div>' ).css( 'margin', '0.7em 0' ).append( el.suchen ), | $( '<div>' ).css( 'margin', '0.7em 0' ).append( el.suchen ), | ||
el.status, | el.status, | ||
| Zeile 342: | Zeile 382: | ||
el.lat.val( String( lat ).replace( '.', ',' ) ); | el.lat.val( String( lat ).replace( '.', ',' ) ); | ||
el.lon.val( String( lon ).replace( '.', ',' ) ); | el.lon.val( String( lon ).replace( '.', ',' ) ); | ||
/* Eine Station ist keine Gemeinde: Leiste hier nicht mitausgeben. */ | |||
el.mitLeiste.prop( 'checked', false ); | |||
letzteSuche = { lat: lat, lon: lon }; | letzteSuche = { lat: lat, lon: lon }; | ||
topStationen = [ { | topStationen = [ { | ||
| Zeile 461: | Zeile 503: | ||
return; | return; | ||
} | } | ||
el. | var text = ''; | ||
'{{Wetterwidget\n' + | if ( el.mitLeiste.prop( 'checked' ) ) { | ||
text += baueLeiste() + '\n'; | |||
} | |||
text += '{{Wetterwidget\n' + | |||
'|ort = ' + $.trim( el.ort.val() ) + '\n' + | '|ort = ' + $.trim( el.ort.val() ) + '\n' + | ||
'|lat = ' + letzteSuche.lat.toFixed( 4 ) + '\n' + | '|lat = ' + letzteSuche.lat.toFixed( 4 ) + '\n' + | ||
| Zeile 469: | Zeile 514: | ||
'|stationsname = ' + ( st.anzeige || st.name ) + '\n' + | '|stationsname = ' + ( st.anzeige || st.name ) + '\n' + | ||
'|stationshoehe = ' + ( st.hoehe !== null ? Math.round( st.hoehe ) : '' ) + '\n' + | '|stationshoehe = ' + ( st.hoehe !== null ? Math.round( st.hoehe ) : '' ) + '\n' + | ||
'}}' | '}}'; | ||
); | el.ausgabe.val( text ); | ||
} | |||
/* Aufruf der [[Vorlage:Gemeindeleiste]]. Die Dienst-Adressen stecken | |||
* in der Vorlage – hier werden nur die Werte geliefert. */ | |||
function baueLeiste() { | |||
var ort = $.trim( el.ort.val() ); | |||
var lat = letzteSuche.lat.toFixed( 4 ); | |||
var lon = letzteSuche.lon.toFixed( 4 ); | |||
return '{{Gemeindeleiste\n' + | |||
'|ort = ' + ort + '\n' + | |||
'|lat = ' + lat + '\n' + | |||
'|lon = ' + lon + '\n' + | |||
'|plz = ' + $.trim( el.plz.val() ) + '\n' + | |||
'|website = ' + $.trim( el.website.val() ) + '\n' + | |||
'|wikipedia = ' + $.trim( el.wikipedia.val() ) + '\n' + | |||
'|pollenloc = ' + pollenLoc( ort, lat, lon ) + '\n' + | |||
'}}'; | |||
} | |||
/* Der MSN-Pollenlink erwartet die Ortsangabe als base64-codiertes | |||
* JSON im loc-Parameter. Wikitext kann nicht base64-codieren, darum | |||
* kocht das Formular den Wert vor. Das Bundesland ist fest auf | |||
* Niederösterreich gesetzt (alle Schwarzatal-Gemeinden liegen dort). | |||
* +, / und = werden URL-sicher ersetzt. */ | |||
function pollenLoc( ort, lat, lon ) { | |||
var daten = { | |||
l: ort, r: 'Niederösterreich', c: 'Österreich', | |||
i: 'AT', g: 'de-de', x: String( lon ), y: String( lat ) | |||
}; | |||
try { | |||
return btoa( unescape( encodeURIComponent( | |||
JSON.stringify( daten ) ) ) ) | |||
.replace( /\+/g, '%2B' ) | |||
.replace( /\//g, '%2F' ) | |||
.replace( /=/g, '%3D' ); | |||
} catch ( e ) { | |||
return ''; | |||
} | |||
} | } | ||
Version vom 25. Juli 2026, 00:34 Uhr
/**
* MediaWiki:Gadget-WetterGenerator.js (Ausbaustufe 3)
* =====================================================================
* Formular zum Erstellen von Wetterwidget-Bausteinen für Gemeindeseiten
* – jetzt zusätzlich mit:
*
* A) WIKIMAP-EXPORT: Ein Klick holt die aktuelle Stationsliste live von
* GeoSphere und erzeugt fertige Einträge für WikiMap-Orte.json
* (Kategorie "Wetterstation", einstellbarer Umkreis, leer = ganz
* Österreich). Die Einträge werden in die Liste "orte" der Datei
* kopiert – am besten VOR einen bestehenden Eintrag, dann stimmen
* die Kommas. Einmalig im Block "kategorien" ergänzen:
* "Wetterstation": "#2a6fb8"
*
* B) KARTEN-RÜCKSPRUNG: Die exportierten Einträge verweisen im Feld
* "seite" auf diese Generator-Seite samt Adress-Parametern
* (ws_station, ws_name, ws_lat, ws_lon, ws_hoehe). Öffnet jemand
* einen Stationsmarker auf der WikiMap und folgt dem Link, steht
* hier sofort der fertige {{Wetterwidget|...}}-Baustein bereit.
*
* C) GEMEINDELEISTE: Das Formular gibt (abwählbar per Häkchen) vor dem
* Wetterwidget-Baustein auch den Aufruf der [[Vorlage:Gemeindeleiste]]
* aus – die Button-Zeile mit Wetter-, Radar-, Wolken-, Nachthimmel-,
* Pollen-, Warnungs-, Website- und Wikipedia-Link. Die Dienst-
* Adressen stecken in der Vorlage (eine Stelle für Änderungen);
* das Formular liefert nur die Werte. Dafür gibt es drei neue
* Eingabefelder (PLZ, Website, Wikipedia). Beim Karten-Rücksprung
* (B) ist das Häkchen automatisch abgewählt, denn eine Station ist
* keine Gemeinde.
*
* Datenquelle: GeoSphere Austria Dataset-API (Open Data, CC BY 4.0),
* kein API-Schlüssel nötig. Doku: https://dataset.api.hub.geosphere.at/v1/docs/
*
* EINRICHTUNG: unverändert gegenüber Ausbaustufe 1 – dieser Code ersetzt
* einfach den bisherigen Inhalt von [[MediaWiki:Gadget-WetterGenerator.js]].
* Der Eintrag in [[MediaWiki:Gadgets-definition]] bleibt gleich:
* * WetterGenerator[ResourceLoader|default|hidden]|WetterGenerator.js
* Die Generator-Seite enthält weiterhin nur:
* <div id="wetter-generator"></div>
* =====================================================================
*/
( function () {
'use strict';
/* Stationsliste der 10-Minuten-Messstationen (TAWES) samt Metadaten */
var META_URL = 'https://dataset.api.hub.geosphere.at/v1/' +
'station/current/tawes-v1-10min/metadata';
/* So viele nächstgelegene Stationen werden zur Auswahl angeboten */
var MAX_STATIONEN = 5;
/* Bezugspunkt für den Export-Umkreis: grobe Mitte des Schwarzatals
* (Raum Payerbach/Gloggnitz). */
var EXPORT_ZENTRUM = { lat: 47.70, lon: 15.95 };
var EXPORT_RADIUS_VORGABE = '50';
var stationen = null; /* geladene Stationsliste (wird nur 1x geholt) */
var topStationen = []; /* Ergebnis der letzten Suche, sortiert */
var letzteSuche = null; /* { lat, lon } der letzten Suche */
var el = {}; /* Referenzen auf die Formularelemente */
$( function () {
var container = document.getElementById( 'wetter-generator' );
if ( container ) {
baueFormular( $( container ) );
uebernimmAusKarte();
}
} );
/* ------------------------------------------------------------------
* Formular aufbauen
* ------------------------------------------------------------------ */
function baueFormular( $container ) {
el.ort = $( '<input>' )
.attr( { type: 'text', placeholder: 'z. B. Reichenau an der Rax' } )
.css( 'width', '20em' )
.on( 'input', aktualisiereBaustein );
el.lat = $( '<input>' )
.attr( { type: 'text', placeholder: 'z. B. 47,6969' } )
.css( 'width', '10em' );
el.lon = $( '<input>' )
.attr( { type: 'text', placeholder: 'z. B. 15,8446' } )
.css( 'width', '10em' );
/* --- Zusatzfelder für die Gemeindeleiste (Button-Zeile) --- */
el.plz = $( '<input>' )
.attr( { type: 'text', placeholder: 'z. B. 2632' } )
.css( 'width', '6em' )
.on( 'input', aktualisiereBaustein );
el.website = $( '<input>' )
.attr( { type: 'text',
placeholder: 'z. B. https://www.gemeinde-altendorf.at/' } )
.css( { width: '100%', 'max-width': '26em' } )
.on( 'input', aktualisiereBaustein );
el.wikipedia = $( '<input>' )
.attr( { type: 'text',
placeholder: 'z. B. https://de.wikipedia.org/wiki/Altendorf_(Niederösterreich)' } )
.css( { width: '100%', 'max-width': '26em' } )
.on( 'input', aktualisiereBaustein );
el.mitLeiste = $( '<input>' )
.attr( { type: 'checkbox' } )
.prop( 'checked', true )
.on( 'change', aktualisiereBaustein );
el.suchen = $( '<button>' )
.attr( 'type', 'button' )
.text( 'Stationen suchen' )
.on( 'click', sucheStationen );
el.status = $( '<div>' ).css( 'margin', '0.7em 0' );
el.liste = $( '<div>' ).css( 'margin', '0.5em 0' );
el.ausgabe = $( '<textarea>' )
.attr( { rows: 8, readonly: 'readonly' } )
.css( textFeldStil() );
el.kopieren = $( '<button>' )
.attr( 'type', 'button' )
.text( 'Baustein kopieren' )
.css( 'display', 'none' )
.on( 'click', function () {
kopiereFeld( el.ausgabe, setzeStatus,
'Baustein kopiert – jetzt auf der Zielseite einfügen.' );
} );
/* --- Export-Bereich (WikiMap) --- */
el.exportRadius = $( '<input>' )
.attr( { type: 'text' } )
.val( EXPORT_RADIUS_VORGABE )
.css( 'width', '6em' );
el.exportKnopf = $( '<button>' )
.attr( 'type', 'button' )
.text( 'Stationen exportieren' )
.on( 'click', exportiereStationen );
el.exportStatus = $( '<div>' ).css( 'margin', '0.7em 0' );
el.exportAusgabe = $( '<textarea>' )
.attr( { rows: 10, readonly: 'readonly' } )
.css( textFeldStil() );
el.exportKopieren = $( '<button>' )
.attr( 'type', 'button' )
.text( 'Einträge kopieren' )
.css( 'display', 'none' )
.on( 'click', function () {
kopiereFeld( el.exportAusgabe, setzeExportStatus,
'Einträge kopiert – jetzt in WikiMap-Orte.json einfügen.' );
} );
el.exportHinweis = $( '<div>' )
.css( { 'margin-top': '0.5em', 'font-size': '85%', color: '#54595d',
display: 'none' } )
.text( 'Einmalig im Block "kategorien" von WikiMap-Orte.json ' +
'ergänzen: "Wetterstation": "#2a6fb8" – dann bekommen die ' +
'Stationen ihre eigene Pinfarbe und ihren Filter.' );
$container.empty().append(
kasten().append(
$( '<p>' ).text(
'Ort und Koordinaten eingeben – das Formular sucht die ' +
'nächstgelegenen GeoSphere-Wetterstationen und erstellt ' +
'den fertigen Baustein für die Gemeindeseite.'
),
feld( 'Ortsname', el.ort ),
feld( 'Breitengrad (Dezimalgrad)', el.lat ),
feld( 'Längengrad (Dezimalgrad)', el.lon ),
feld( 'PLZ (für den Wetterlink der Leiste)', el.plz ),
feld( 'Gemeinde-Website (optional)', el.website ),
feld( 'Wikipedia-Adresse (optional)', el.wikipedia ),
$( '<label>' )
.css( { display: 'block', margin: '0.6em 0' } )
.append( el.mitLeiste, document.createTextNode(
' Gemeindeleiste (Button-Zeile) mit ausgeben' ) ),
$( '<div>' ).css( 'margin', '0.7em 0' ).append( el.suchen ),
el.status,
el.liste,
el.ausgabe,
$( '<div>' ).css( 'margin', '0.5em 0' ).append( el.kopieren )
),
kasten().css( 'margin-top', '1em' ).append(
$( '<div>' )
.css( { 'font-weight': 'bold', 'margin-bottom': '0.3em' } )
.text( 'Stationen für die WikiMap' ),
$( '<p>' ).css( 'margin', '0.3em 0' ).text(
'Erzeugt fertige Einträge für WikiMap-Orte.json – alle ' +
'derzeit aktiven Wetterstationen im gewählten Umkreis. ' +
'Der Klick auf einen Stationsmarker der Karte führt ' +
'danach hierher zurück und liefert sofort den passenden ' +
'Widget-Baustein.'
),
feld( 'Umkreis in km (leer = ganz Österreich)', el.exportRadius ),
$( '<div>' ).css( 'margin', '0.7em 0' ).append( el.exportKnopf ),
el.exportStatus,
el.exportAusgabe,
$( '<div>' ).css( 'margin', '0.5em 0' ).append( el.exportKopieren ),
el.exportHinweis
),
$( '<div>' )
.css( { 'margin-top': '0.8em', 'font-size': '85%', color: '#54595d' } )
.text( 'Stationsdaten: GeoSphere Austria, Dataset-API (CC BY 4.0)' )
);
}
function kasten() {
return $( '<div>' ).css( {
border: '1px solid #a2a9b1',
background: '#f8f9fa',
padding: '1em',
'max-width': '42em'
} );
}
function feld( beschriftung, $eingabe ) {
return $( '<div>' ).css( 'margin', '0.5em 0' ).append(
$( '<label>' )
.css( { display: 'block', 'font-weight': 'bold' } )
.text( beschriftung ),
$eingabe
);
}
function textFeldStil() {
return {
width: '100%',
'max-width': '38em',
'font-family': 'monospace',
display: 'none'
};
}
/* ------------------------------------------------------------------
* Stationsliste laden (gemeinsam für Suche und Export)
* ------------------------------------------------------------------ */
function ladeStationsliste( beiErfolg, beiFehler ) {
if ( stationen ) {
beiErfolg();
return;
}
$.getJSON( META_URL )
.done( function ( daten ) {
stationen = lesbareStationen( daten );
if ( !stationen.length ) {
stationen = null;
beiFehler( 'Die Antwort der GeoSphere-API enthielt keine ' +
'Stationen. Bitte später erneut versuchen.' );
return;
}
beiErfolg();
} )
.fail( function ( antwort ) {
beiFehler( ladeFehlerText( antwort ) );
} );
}
function ladeFehlerText( antwort ) {
if ( !antwort || antwort.status === 0 ) {
return 'Die Stationsliste konnte nicht geladen werden: Der Browser ' +
'hat die Anfrage blockiert oder es besteht keine ' +
'Internetverbindung.';
}
return 'Die Stationsliste konnte nicht geladen werden (Serverantwort ' +
antwort.status + '). Bitte später erneut versuchen.';
}
/* API-Antwort in eine einheitliche Stationsliste umwandeln */
function lesbareStationen( daten ) {
var roh = ( daten && daten.stations ) || [];
var ergebnis = [];
$.each( roh, function ( i, st ) {
var lat = holeZahl( st, [ 'lat', 'latitude' ] );
var lon = holeZahl( st, [ 'lon', 'longitude' ] );
var name;
if ( lat === null || lon === null ) {
return; /* ohne Koordinaten unbrauchbar */
}
if ( st.is_active === false ) {
return; /* stillgelegte Stationen ausblenden */
}
name = String( st.name || 'Unbenannte Station' );
ergebnis.push( {
id: String( st.id ),
name: name,
anzeige: huebscherName( name ),
bundesland: st.state ? String( st.state ) : '',
lat: lat,
lon: lon,
hoehe: holeZahl( st, [ 'altitude', 'elevation' ] )
} );
} );
return ergebnis;
}
/* ------------------------------------------------------------------
* Einzel-Suche (unverändertes Verhalten)
* ------------------------------------------------------------------ */
function sucheStationen() {
var lat = parseKoordinate( el.lat.val() );
var lon = parseKoordinate( el.lon.val() );
if ( lat === null || lon === null ) {
setzeStatus( 'Bitte beide Koordinaten in Dezimalgrad eingeben, ' +
'z. B. 47,6969 und 15,8446.', true );
return;
}
letzteSuche = { lat: lat, lon: lon };
setzeStatus( 'Stationsliste wird geladen …', false );
ladeStationsliste( werteAus, function ( fehlerText ) {
setzeStatus( fehlerText, true );
} );
}
function werteAus() {
var i;
for ( i = 0; i < stationen.length; i++ ) {
stationen[ i ].entfernung = entfernungKm(
letzteSuche.lat, letzteSuche.lon,
stationen[ i ].lat, stationen[ i ].lon
);
}
topStationen = stationen.slice().sort( function ( a, b ) {
return a.entfernung - b.entfernung;
} ).slice( 0, MAX_STATIONEN );
var hinweis = 'Nächstgelegene Stationen – die erste ist vorausgewählt:';
if ( !imBereichOesterreich( letzteSuche.lat, letzteSuche.lon ) ) {
hinweis = 'Achtung: Die Koordinaten liegen außerhalb Österreichs – ' +
'bitte prüfen. ' + hinweis;
}
setzeStatus( hinweis, false );
el.liste.empty();
$.each( topStationen, function ( idx, st ) {
el.liste.append( radioZeile( idx, st.anzeige +
( st.bundesland ? ' (' + st.bundesland + ')' : '' ) +
' – ' + formatKm( st.entfernung ) + ' entfernt, ' +
( st.hoehe !== null ?
Math.round( st.hoehe ) + ' m Seehöhe' : 'Höhe unbekannt' ),
idx === 0 ) );
} );
el.ausgabe.show();
el.kopieren.show();
aktualisiereBaustein();
}
function radioZeile( idx, beschreibung, angehakt ) {
return $( '<label>' )
.css( { display: 'block', margin: '0.25em 0' } )
.append(
$( '<input>' )
.attr( { type: 'radio', name: 'wg-station' } )
.val( idx )
.prop( 'checked', angehakt )
.on( 'change', aktualisiereBaustein ),
document.createTextNode( ' ' + beschreibung )
);
}
/* ------------------------------------------------------------------
* Rücksprung von der WikiMap: ?ws_station=...&ws_lat=...
* ------------------------------------------------------------------ */
function uebernimmAusKarte() {
var id = leseUrlParameter( 'ws_station' );
var lat = parseKoordinate( leseUrlParameter( 'ws_lat' ) || '' );
var lon = parseKoordinate( leseUrlParameter( 'ws_lon' ) || '' );
var name, hoehe;
if ( !id || lat === null || lon === null ) {
return;
}
name = leseUrlParameter( 'ws_name' ) || ( 'Nr. ' + id );
hoehe = parseKoordinate( leseUrlParameter( 'ws_hoehe' ) || '' );
el.ort.val( name );
el.lat.val( String( lat ).replace( '.', ',' ) );
el.lon.val( String( lon ).replace( '.', ',' ) );
/* Eine Station ist keine Gemeinde: Leiste hier nicht mitausgeben. */
el.mitLeiste.prop( 'checked', false );
letzteSuche = { lat: lat, lon: lon };
topStationen = [ {
id: id, name: name, anzeige: name, bundesland: '',
lat: lat, lon: lon, hoehe: hoehe, entfernung: 0
} ];
setzeStatus( 'Station aus der Karte übernommen – der Baustein steht ' +
'unten bereit. Für andere Vorschläge einfach „Stationen suchen" ' +
'klicken.', false );
el.liste.empty().append( radioZeile( 0, name +
( hoehe !== null ? ', ' + Math.round( hoehe ) + ' m Seehöhe' : '' ) +
' (aus der Karte übernommen)', true ) );
el.ausgabe.show();
el.kopieren.show();
aktualisiereBaustein();
}
function leseUrlParameter( name ) {
var treffer = new RegExp( '[?&]' + name + '=([^&#]*)' )
.exec( location.search );
if ( !treffer ) {
return null;
}
try {
return decodeURIComponent( treffer[ 1 ].replace( /\+/g, ' ' ) );
} catch ( e ) {
return null;
}
}
/* ------------------------------------------------------------------
* Export für WikiMap-Orte.json
* ------------------------------------------------------------------ */
function exportiereStationen() {
var radiusText = $.trim( el.exportRadius.val() );
var radius = radiusText === '' ? null : parseKoordinate( radiusText );
if ( radiusText !== '' && ( radius === null || radius <= 0 ) ) {
setzeExportStatus( 'Bitte einen Umkreis in Kilometern angeben – ' +
'oder das Feld leeren für ganz Österreich.', true );
return;
}
setzeExportStatus( 'Stationsliste wird geladen …', false );
ladeStationsliste( function () {
baueExport( radius );
}, function ( fehlerText ) {
setzeExportStatus( fehlerText, true );
} );
}
function baueExport( radius ) {
var treffer = [];
var zeilen = [];
var i, st;
for ( i = 0; i < stationen.length; i++ ) {
st = stationen[ i ];
if ( radius === null || entfernungKm( EXPORT_ZENTRUM.lat,
EXPORT_ZENTRUM.lon, st.lat, st.lon ) <= radius ) {
treffer.push( st );
}
}
if ( !treffer.length ) {
setzeExportStatus( 'Keine Station im gewählten Umkreis gefunden – ' +
'bitte den Umkreis vergrößern.', true );
return;
}
treffer.sort( function ( a, b ) {
return a.anzeige.localeCompare( b.anzeige );
} );
for ( i = 0; i < treffer.length; i++ ) {
st = treffer[ i ];
zeilen.push( ' { "id": ' +
JSON.stringify( 'Wetterstation ' + st.anzeige ) +
', "lat": ' + st.lat.toFixed( 4 ) +
', "lon": ' + st.lon.toFixed( 4 ) +
', "kategorie": "Wetterstation"' +
', "seite": ' + JSON.stringify( urlFuerStation( st ) ) +
' },' );
}
el.exportAusgabe.val( zeilen.join( '\n' ) ).show();
el.exportKopieren.show();
el.exportHinweis.show();
setzeExportStatus( treffer.length + ' Stationen bereit. Den Block in ' +
'die Liste "orte" von WikiMap-Orte.json einfügen – am besten VOR ' +
'einen bestehenden Eintrag, dann stimmen die Kommas. Die ' +
'JSON-Seite meldet beim Speichern selbst, falls eines fehlt.',
false );
}
/* Absolute Adresse dieser Generator-Seite samt Stations-Parametern.
* Absolut deshalb, weil die WikiMap externe Ziele (http/https)
* unverändert übernimmt – Wiki-Seitennamen dagegen könnten keine
* Parameter tragen. */
function urlFuerStation( st ) {
return location.protocol + '//' + location.host +
mw.config.get( 'wgScript' ) +
'?title=' + encodeURIComponent( mw.config.get( 'wgPageName' ) ) +
'&ws_station=' + encodeURIComponent( st.id ) +
'&ws_name=' + encodeURIComponent( st.anzeige ) +
'&ws_lat=' + st.lat.toFixed( 4 ) +
'&ws_lon=' + st.lon.toFixed( 4 ) +
( st.hoehe !== null ? '&ws_hoehe=' + Math.round( st.hoehe ) : '' );
}
/* ------------------------------------------------------------------
* Baustein erzeugen und kopieren
* ------------------------------------------------------------------ */
function aktualisiereBaustein() {
var gewaehlt = el.liste.find( 'input:checked' ).val();
if ( gewaehlt === undefined || !letzteSuche ) {
return;
}
var st = topStationen[ parseInt( gewaehlt, 10 ) ];
if ( !st ) {
return;
}
var text = '';
if ( el.mitLeiste.prop( 'checked' ) ) {
text += baueLeiste() + '\n';
}
text += '{{Wetterwidget\n' +
'|ort = ' + $.trim( el.ort.val() ) + '\n' +
'|lat = ' + letzteSuche.lat.toFixed( 4 ) + '\n' +
'|lon = ' + letzteSuche.lon.toFixed( 4 ) + '\n' +
'|station = ' + st.id + '\n' +
'|stationsname = ' + ( st.anzeige || st.name ) + '\n' +
'|stationshoehe = ' + ( st.hoehe !== null ? Math.round( st.hoehe ) : '' ) + '\n' +
'}}';
el.ausgabe.val( text );
}
/* Aufruf der [[Vorlage:Gemeindeleiste]]. Die Dienst-Adressen stecken
* in der Vorlage – hier werden nur die Werte geliefert. */
function baueLeiste() {
var ort = $.trim( el.ort.val() );
var lat = letzteSuche.lat.toFixed( 4 );
var lon = letzteSuche.lon.toFixed( 4 );
return '{{Gemeindeleiste\n' +
'|ort = ' + ort + '\n' +
'|lat = ' + lat + '\n' +
'|lon = ' + lon + '\n' +
'|plz = ' + $.trim( el.plz.val() ) + '\n' +
'|website = ' + $.trim( el.website.val() ) + '\n' +
'|wikipedia = ' + $.trim( el.wikipedia.val() ) + '\n' +
'|pollenloc = ' + pollenLoc( ort, lat, lon ) + '\n' +
'}}';
}
/* Der MSN-Pollenlink erwartet die Ortsangabe als base64-codiertes
* JSON im loc-Parameter. Wikitext kann nicht base64-codieren, darum
* kocht das Formular den Wert vor. Das Bundesland ist fest auf
* Niederösterreich gesetzt (alle Schwarzatal-Gemeinden liegen dort).
* +, / und = werden URL-sicher ersetzt. */
function pollenLoc( ort, lat, lon ) {
var daten = {
l: ort, r: 'Niederösterreich', c: 'Österreich',
i: 'AT', g: 'de-de', x: String( lon ), y: String( lat )
};
try {
return btoa( unescape( encodeURIComponent(
JSON.stringify( daten ) ) ) )
.replace( /\+/g, '%2B' )
.replace( /\//g, '%2F' )
.replace( /=/g, '%3D' );
} catch ( e ) {
return '';
}
}
function kopiereFeld( $feld, statusSetzer, erfolgsMeldung ) {
var text = $feld.val();
if ( !text ) {
statusSetzer( 'Noch nichts zu kopieren vorhanden.', true );
return;
}
function fallback() {
try {
$feld[ 0 ].select();
document.execCommand( 'copy' );
statusSetzer( erfolgsMeldung, false );
} catch ( e ) {
statusSetzer( 'Kopieren nicht möglich – bitte den Text im ' +
'Feld markieren und manuell kopieren.', true );
}
}
if ( navigator.clipboard && navigator.clipboard.writeText ) {
navigator.clipboard.writeText( text ).then( function () {
statusSetzer( erfolgsMeldung, false );
}, fallback );
} else {
fallback();
}
}
/* ------------------------------------------------------------------
* Kleine Helfer
* ------------------------------------------------------------------ */
/* GROSSSCHREIBUNG der API hübsch umwandeln: "WIEN/HOHE WARTE" wird zu
* "Wien/Hohe Warte", "LUNZ AM SEE" zu "Lunz am See". Umlaut-
* Umschreibungen (OE/UE/AE) werden nur zurückgewandelt, wenn kein
* Vokal davorsteht – so bleibt "Feuerkogel" verschont. Heuristik:
* Einzelfälle lassen sich im JSON-Export nachträglich anpassen. */
function huebscherName( roh ) {
var fuellwoerter = [ 'am', 'an', 'im', 'in', 'bei', 'ob', 'auf',
'unter', 'der', 'die', 'das', 'und', 'zu' ];
var text = String( roh || '' ).toLowerCase()
.replace( /(^|[^aeiouq])ae/g, '$1ä' )
.replace( /(^|[^aeiouq])oe/g, '$1ö' )
.replace( /(^|[^aeiouq])ue/g, '$1ü' )
.replace( /(^|[\s\/\-.(])([a-zäöü])/g, function ( ganz, davor, buchstabe ) {
return davor + buchstabe.toUpperCase();
} );
var teile = text.split( ' ' );
var i;
for ( i = 1; i < teile.length; i++ ) {
if ( $.inArray( teile[ i ].toLowerCase(), fuellwoerter ) !== -1 ) {
teile[ i ] = teile[ i ].toLowerCase();
}
}
return teile.join( ' ' );
}
function parseKoordinate( text ) {
var bereinigt = String( text || '' )
.replace( /,/g, '.' )
.replace( /[^0-9.\-]/g, '' );
var wert = parseFloat( bereinigt );
return isFinite( wert ) ? wert : null;
}
function holeZahl( objekt, namen ) {
var i, wert;
for ( i = 0; i < namen.length; i++ ) {
wert = parseFloat( objekt[ namen[ i ] ] );
if ( isFinite( wert ) ) {
return wert;
}
}
return null;
}
/* Luftlinie in Kilometern (Haversine-Formel) */
function entfernungKm( lat1, lon1, lat2, lon2 ) {
var rad = Math.PI / 180;
var dLat = ( lat2 - lat1 ) * rad;
var dLon = ( lon2 - lon1 ) * rad;
var a = Math.sin( dLat / 2 ) * Math.sin( dLat / 2 ) +
Math.cos( lat1 * rad ) * Math.cos( lat2 * rad ) *
Math.sin( dLon / 2 ) * Math.sin( dLon / 2 );
return 6371 * 2 * Math.atan2( Math.sqrt( a ), Math.sqrt( 1 - a ) );
}
function imBereichOesterreich( lat, lon ) {
return lat >= 46.3 && lat <= 49.1 && lon >= 9.4 && lon <= 17.3;
}
function formatKm( km ) {
return km.toFixed( 1 ).replace( '.', ',' ) + ' km';
}
function setzeStatus( text, istFehler ) {
el.status
.text( text )
.css( 'color', istFehler ? '#b32424' : '#202122' );
}
function setzeExportStatus( text, istFehler ) {
el.exportStatus
.text( text )
.css( 'color', istFehler ? '#b32424' : '#202122' );
}
}() );