schule-suchen

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Nächste Überarbeitung
Vorhergehende Überarbeitung
schule-suchen [09.10.2022 18:56] – angelegt whupfeldschule-suchen [17.10.2022 07:55] (aktuell) whupfeld
Zeile 1: Zeile 1:
-====== Openweathermap ======+====== Schule suchen in NRW ======
  
-Von der Webseite www.openweathermap.com kann man per REST-Schnittstelle kostenlos die aktuellen Wetterdaten von Orten weltweit herunterladenKostenlos ist der Service allerdings nur, wenn mann weniger als 60 Aufrufe pro Minute hat, für größere Klickzahlen muss man einen kostenpflichtigen Service in Anspruch nehmen.+[[https://www.bankerheide.de/schule-suchen/|{{:bildschirmfoto_2018-02-19_um_21.47.44.png?direct&360|www.bankerheide.de/schule-suchen/}}]]
  
-Über die Güte der Daten kann ich keine Angaben machenNach meinen Beobachtungen gibt es schon einige Abweichungen von meinen Wetterbeobachtungen und anderen Wetterdiensten.+Das [[https://www.schulministerium.nrw.de/docs/bp/Ministerium/Open_MSB/Open_Data/|Ministerium für Schule und Bildung]] in Nordrhein-Westfalen veröffentlicht im Rahmen der Landesinitiative Open NRW Schuldaten unter einer [[https://www.govdata.de/dl-de/by-2-0|Offenen Lizenz]]. Neben einer tagesaktuellen Adressliste werden zusätzliche Bildungsangebote veröffentlicht, z.B. das Kursangebot in der gymnasialen Oberstufe, bilingualer Unterricht und die Schülerzahlen der einzelnen Schulen.
  
-===== API =====+Die Daten werden in Form von CSV- oder XML-Dateien zur Verfügung gestellt, es existiert keine API zum Abruf der Daten.
  
-Um den Dienst nutzen zu könnenmuss man sich Registrieren und einen API-Key generierender bei den Aufrufen mitgeschickt werden muss. Die API ist auf der Seite http://openweathermap.com/api ausführlich erläutert.+Die Idee war, diese Daten in einer Webapplikation so zur Verfügung zu stellendass sich komfortable nach einzelnen Schulen suchen lässtaber auch die Schulen einer Gemeinde oder Stadt angezeigt werden können.
  
-Es gibt eine API für das aktuelle Wetter, kostenlos auch für eine 5-Tage-Wettervorhersage, Umweltdaten, etcIch habe im Folgenden nur die API für das aktuelle Wetter benutztDer Aufruf dazu lautet:+Entstanden ist dabei eine [[https://de.wikipedia.org/wiki/Single-Page-Webanwendung|Single-Page-Webanwendung]] (SPA) auf Basis von Angular JSDie Restschnittstelle wurde mit PHP programmiert.
  
-http://samples.openweathermap.org/data/2.5/weather?id=2172797&appid=b6907d289e10d714a6e88b30761fae22+===== Aufbau der Datenstruktur und Einlesen der Daten =====
  
-Als Parameter mitgeliefert wird die ''id'' der Stadt und die oben beschriebene ''appid''.+Die Schuladressen werden in einer Tabelle geliefert, wobei die einzelnen Attribute mit Schlüsseltabellen erläutert werden. Aus den vorgegebenen Dateien habe ich eine Datenbank abgeleitet, in die dann automatisiert die Dateien importiert.
  
-===== Ermitteln der Stadt-Id ===== 
-Es gibt eine vollständige Liste mit allen Städte-IDs zum [[http://bulk.openweathermap.org/sample/city.list.json.gz|Download]]. Dort sucht man sich die gewünschte ID heraus.  
  
-===== Aufruf der Schnittstelle ===== +==== Datenstruktur ==== 
-In PHP wurde das mit folgendem Codebeispiel umgesetzt. Die Daten stehen dann in einem Array zur Verfügung, dass man sich gut auf dem Bildschirm ausgeben und analysieren kann:  +
-<code php> +
-$url = "http://api.openweathermap.org/data/2.5/weather?id=6553135&lang=de&appid=xxputyourownkeyxxx"; +
-$data = file_get_contents($url); +
-$arrData = json_decode($data,true); +
-echo "<pre>";  print_r ($arrData); echo "</pre>"; +
-</code> +
-Die Ausgabe sieht dann folgendermaßen aus: +
-<code json> +
-Array +
-+
-    [coord] => Array +
-        ( +
-            [lon] => 7.81 +
-            [lat] => 51.68 +
-        ) +
-    [weather] => Array +
-        ( +
-            [0] => Array +
-                ( +
-                    [id] => 800 +
-                    [main] => Clear +
-                    [description] => Klarer Himmel +
-                    [icon] => 01d +
-                )+
  
-        ) +Bei der Datenstruktur wurde bewusst auf Constrains verzichtet, da diese beim Einlesen Probleme bereitetenDas ist keine ganz saubere Lösung, hat aber noch keine Probleme verursacht.
-    [base] => stations +
-    [main] => Array +
-        ( +
-            [temp] => 277.15 +
-            [pressure] => 1018 +
-            [humidity] => 55 +
-            [temp_min] => 277.15 +
-            [temp_max] => 277.15 +
-        ) +
-    [visibility] => 10000 +
-    [wind] => Array +
-        ( +
-            [speed] => 1.5 +
-            [deg] => 190 +
-        ) +
-    [clouds] => Array +
-        ( +
-            [all] => 0 +
-        ) +
-    [dt] => 1519050000 +
-    [sys] => Array +
-        ( +
-            [type] => 1 +
-            [id] => 4912 +
-            [message] => 0.0223 +
-            [country] => DE +
-            [sunrise] => 1519022051 +
-            [sunset] => 1519059102 +
-        ) +
-    [id] => 6553135 +
-    [name] => Hamm, Stadt +
-    [cod] => 200 +
-+
-</code>+
  
-Die Temperaturen sind in Kelvin angegeben und müssen in ºC umgerechnet werden. +  * [[create_schuladressen.sql|Datenbankdefinition]]
-===== Umsetzung mit PHP ===== +
-Die Umsetzung ist jetzt relativ einfach. Die Windstärke ist in der Einheit m/s angegeben. Dort habe ich eine Umrechnung in Windstärken vorgenommen ([[https://de.wikipedia.org/wiki/Beaufortskala|Beaufort-Skala]]). In der Include-Datei ''beaufort-skala.php'' gibt es die Funktion ''getBeaufort()'', die ein Array aus Windstärke und Windstärkenbeschreibung liefert.+
  
-Da die Windrichtung ebenfalls nur in Grad angegeben wird, habe ich dort zusätzlich eine Prozedur ''getWindrichtung()'' eingefügt, die die meteorologischen Bezeichnungen Nord, Nordost , Ost , ... liefert. 
  
-<code php> +==== Script zum Einlesen der Daten ====
-<?php+
  
-   /* ********************************************************************* +Die Anwendung zum Einlesen der Daten besteht aus drei Skripten. In der [[refresh/index.php|index.php]] werden die Tabellen ausgewählt, in der [[refresh/config.php|config.php]] stehen die Adressen und Zugangsdaten, in [[refresh/refresh.php|refresh.php]] findet der eigentliche Einlesevorgang stattAls CSS-Framework kommt Bootstrap3 zum Einsatz, das per CDN eingelesen wird. Die Daten werden jeweils in den Tabellen vor dem Einlesen gelöscht (truncate). Die Spaltenüberschriften entsprechen den Attributen in der Datenbanknur E-Mail wird in E_Mail konvertiert.
-   * Walter Hupfeld - created 18.02.2018 +
-   * Auslesen von OpenWeather-Daten +
-   * ********************************************************************* */ +
-    +
-    require("beaufort-skala.php"); +
-    +
-    $url = "http://api.openweathermap.org/data/2.5/weather?id=6553135&lang=de&appid=xxputyourownkeyxxx"; +
-    $data = file_get_contents($url)+
-    $arrData = json_decode($data,true);+
  
-    $numTemp =     round($arrData['main']['temp'] - 273.15,2); +  * [[refresh/index.php|index.php]] 
-    $numHumidity = $arrData['main']['humidity']; +  [[refresh/config.php|config.php]] 
-    $numPressure = $arrData['main']['pressure']+  [[refresh/refresh.php|refresh.php]]
-    $numTempMax =  round($arrData['main']['temp_max'] - 273.15,2); +
-    $numTempMin =  round($arrData['main']['temp_min'] - 273.15,2); +
-     +
-    $strSunrise = date(" H:i", $arrData['sys']['sunrise']); +
-    $strSunset = date(" H:i", $arrData['sys']['sunset']);+
  
-    $numWind $arrData['wind']['speed']; +===== Die REST-Schnittstelle =====
-    $strWinddescription getBeaufort($numWind)[0]; +
-    $numWindspeed  getBeaufort($numWind)[1];+
  
-    $numWindDirection = $arrData['wind']['deg']; +Die [[https://de.wikipedia.org/wiki/Representational_State_Transfer|REST]]-Schnittstelle liefert die Daten per [[https://de.wikipedia.org/wiki/JavaScript_Object_Notation|JSON]]-Records und wurde ebenfalls mit PHP realisiertDie Datenabfrage wurde auf mehrere Dateien verteiltwas mit der Entstehungsgeschichte des Projekts zusammenhängtMann könnte sicherlich die verschieden Datensätze über geeignete Parameter aus einem Skript auslesen
-    $strWindDescription = getWindrichtung($numWindDirection)[0]; +  
-?> +==== Suchfunktionen ====
-<!doctype html> +
-<html lang="de"> +
-<head> +
-    <meta charset="utf-8"> +
-    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> +
-    <meta http-equiv="refresh" content="300"> +
-    <title>Wetterstation</title> +
-    <!-- Latest compiled and minified CSS --> +
-    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"> +
-<style> +
-  .maintemp {font-size:2em; font-weight:bold;+
-  .icon {margin-bottom:20px;+
-  .weather {width:30em;+
-  .weatherdesc {font-size:1.4em;+
-</style> +
-</head> +
-<body> +
-  <div class="container"> +
-    <h2>Wetterdaten für <?= $arrData['name']?></h2> +
-    <img class="icon" src="https://openweathermap.org/img/w/<?= $arrData['weather'][0]['icon'] ?>.png" /> +
-    <span class="maintemp"> <?= round($numTemp,0) ?> &deg;C</span><br> +
-    <!-- <?= $arrData['weather'][0]['main'] ?>--> +
-   <p class="weatherdesc"> <?= $arrData['weather'][0]['description'] ?> </p> +
-   <p><?= date("d.m.Y") ?> <?= date("H:i")?> Uhr</p> +
-    <table class="table table-striped table-bordered weather"> +
-    <tbody> +
-     <tr><td>Temperatur</td>  <td><?$numTemp ?> &deg;C Min: <?$numTempMin ?>&deg;C Max: <?$numTempMax ?> &deg;C</td></tr> +
-     <tr><td>Wind</td>        <td><?$strWinddescription ?>, Windstärke <?$numWindspeed ?>, <?$numWind?> m/s  +
-                             <?$strWindDescription ?> (<?=$numWindDirection?>&deg;)</td></tr> +
-     <tr><td>Wolken</td>      <td><?= $arrData['clouds']['all'];?> %</td></tr> +
-     <tr><td>Luftdruck</td>    <td><?= $numPressure ?> hPa</td></tr> +
-     <tr><td>Luftfeuchtigkeit</td><td><?= $numHumidity ?> %</td></tr> +
-     <tr><td>Sichtweite</td>    <td><?= $arrData['visibility'];?></td></tr> +
-     <tr><td>Sonenaufgang</td>  <td><?= $strSunrise ?> Uhr</td></tr> +
-     <tr><td>Sunnenuntergang</td> <td><?= $strSunset ?> Uhr</td></tr> +
-     </tbody> +
-     </table> +
  
- <p>Quelle: <a href="https://openweathermap.org/city/2911240">www.openweathermap.com</a></p>    
-</div> 
-</body> 
-</html>     
-</code> 
  
-  * [[https://www.bankerheide.de/wetter/|Skript ausführen]]+Es werden für die Applikation zwei Suchfunktionen verwendet, einmal die Suche nach einer Schule. Das Skript [[ajax/search.php|search.php]] liefert eine **Liste mit Schulen**. Gesucht wird in den Felder für die Schulnummer, den Namen, PLZ und Ort der Schule. Der Suchstring kann mit Leerzeichen getrennt werden, wobei die jeweiligen Suchbegriffe dann jeweils per __Und__ verknüpft werden.
  
-===== Windstärke und Windrichtung ===== +Das Skript [[ajax/search_gemeinden.php|search_gemeinden.php]] sucht in der Gemeindetabelle und liefert eine auf 30 begrenzte Liste der Gemeindetreffer.
-Die Ermittlung der Windstärke und der Windrichtung lässt sich sicherlich kürzer und eleganter lösen.+
  
-<code php> 
-<?php 
-/* ********************************************************************* 
- 
-* Walter Hupfeld - created 18.02.2018 
-* Windstärkenskala und Windstärkenbezeichnung nach Beaufort 
-* 
-* ********************************************************************* */ 
  
-$arrBeaufort = array ( +  [[ajax/search.php|search.php]
-   ['windstaerke' => 0, 'beschreibung' => 'Windstille', 'minwert' => 0  ], +  [[ajax/search_gemeinden.php|search_gemeinden.php]
-   ['windstaerke' => 1, 'beschreibung' => 'leiser Zug', 'minwert' => 0.3  ], + 
-   ['windstaerke' => 2, 'beschreibung' => 'leichte Brise', 'minwert' => 1.6  ], +==== Schuldaten ===
-   ['windstaerke' => 3, 'beschreibung' => 'schwache Brise', 'minwert' => 3.4  ], +Das Skript [[ajax/get_schule.php|get_schule.php]liefert alle Daten einer Schulederen id als Parameter übermittelt wird. Der Aufruf https://bankerheide.de/schule-suchen/ajax/get_schule.php?snr=169560 liefert den Datensatz der Schule mit der Schulnummer 169569 im JSON-Format. 
-   ['windstaerke' => 4'beschreibung' => 'mäßige Brise''minwert' => 5.5  ], + 
-   ['windstaerke' => 5'beschreibung' => 'frische Brise''minwert' => 8. ], +Im Datensatz ist auch eine **Georeferenzierung** der Schule enthaltenleider nicht in Längen- und Breitengradensonder in [[https://de.wikipedia.org/wiki/Gau%C3%9F-Kr%C3%BCger-Koordinatensystem|Gauß-Krüger-Koordinatsystem]]. Um die Geodaten benutzen zu könnenum die die Lage Schule auf einer Karte darstellen zu könnenmüssen die Koordinaten aus dem Gauß-Krüger-System in Längen und Breitengrade umgerechnet werden. Da das ziemlich kompliziert isthabe ich ein Javascript-Programm von http://calc.gknavigation.de/ in PHP adaptiert. 
-   ['windstaerke' => 6, 'beschreibung' => 'staker Wind', 'minwert' => 10.8  ], + 
-   ['windstaerke' => 7, 'beschreibung' => 'steifer Wind', 'minwert' => 12.9  ], +  * [[ajax/get_schule.php|get_schule.php]
-   ['windstaerke' => 8, 'beschreibung' => 'stürmische Wind', 'minwert' => 17.2  ]+  [[ajax/geoconvert.php|geoconvert.php]] (Umrechnung von Gauß-Krüger-Koordinaten in Längen- und Breitengrade) 
-   ['windstaerke' => 9, 'beschreibung' => 'Sturm', 'minwert' => 20.8  ], + 
-   ['windstaerke' => 10, 'beschreibung' => 'schwerer Sturm', 'minwert' => 24.5  ], +==== Gemeinden ==== 
-   ['windstaerke' => 11, 'beschreibung' => 'orkanartiger Sturm', 'minwert' => 28. ], + 
-   ['windstaerke' => 12, 'beschreibung' => 'Orkan', 'minwert' => 32.7  ], +Das Skript [[ajax/get_gm_schulen.php|get_gm_schulen.php]] liefert die Schulen einer Gemeinde. Als Parameter dient die Gemeindekennziffer.Das zweite Skript liefert statistische Daten einer jeden Gemeine wie Anzahl der Schulen einer Schulform und die dazugehörigen Schülerzahlen. Auch das Skript [[ajax/get_statistcs.php|get_statistc.php]] wird mit der Gemeindekennziffer aufgerufen. 
-); + 
-  + 
-function getBeaufort($numV) { +  * [[ajax/get_gm_schulen.php|get_gm_schulen.php]
-    global $arrBeaufort; +  [[ajax/get_statistcs.php|get_statistc.php]] 
-    $strDescription=""; + 
-    $numSpeeds=0; +==== Weitere Daten ==== 
-    foreach ($arrBeaufort as $wind) { +Es gibt zwei weiter Skripte, Das erste liest das Kursangebot in der Gymnasialen Oberstufe aus, das zweite Daten zu Bilingualen Angeboten an Schulen, die ebenfalls vom MSB angeboten werden. 
-        if ($wind['minwert'<= $numV) { + 
-            $strDescription = $wind['beschreibung']; +  * [[ajax/get_kurse.php|get_kurse.php]
-            $numSpeeds = $wind['windstaerke']; +  [[ajax/get_bilingual.php|get_bilingual.php]
-        } else break; + 
-    } +===== Die Applikation ===== 
-    return [$strDescription,$numSpeeds]; +Die [[https://bankerheide.de/schule-suchen/|Applikation]] selber ist als Single-Page-Webapplikation im Prinzip eine HTML-Datei. Als Javascript-Framework wurde [[https://de.wikipedia.org/wiki/AngularJS|AngularJS]] 1. verwendet. Für mich war das eine Gelegenheit, das Framework an einem sinnvollen Beispiel auszuprobieren. Ich bin keine Experte für AngularJS, hier geht sicherlich noch mehr. Aber für einen ersten Einblick das Framework war die Programmierung der Anwendung sicherlich nützlich. 
-}+ 
 +Neben AngularJS wurden noch Bootstrap 4 als Javascript-Framwork und [[http://leaflet.org/|Leaflet]] als Modul für die Darstellung der Karten und [[http://tombatossals.github.io/angular-leaflet-directive/#!/|angular-leaflet-directive]] für die Einbindung in AngularJS verwendet. Die Quelltexte sind im Folgenden dokumentiert. 
 + 
 +  [[schulesuchen/index.html|index.html]] [[https://bankerheide.de/schule-suchen/|Web]
 +  * [[schulesuchen/app.js|app.js]]
  
 +Gerade bei der Zusammenarbeit mit Leaflet gibt es einige Probleme, die ich nicht alle zufriedenstellend lösen konnte. Es gibt auch einen Fehler bei der Aktualisierung der Kursangebote.
  
-$arrWindrichtung array ( +===== Download =====
-    ["bezeichnung" => "Nord", "kurzbez" => "N", "winkel" => 0], +
-    ["bezeichnung" => "Nordost", "kurzbez" => "NE", "winkel" => 22.5], +
-    ["bezeichnung" => "Ost", "kurzbez" => "E", "winkel" => 67.5], +
-    ["bezeichnung" => "Südost", "kurzbez" => "SE", "winkel" => 112.5], +
-    ["bezeichnung" => "Süd", "kurzbez" => "S", "winkel" => 157.5], +
-    ["bezeichnung" => "Südwest", "kurzbez" => "SW", "winkel" => 202.5], +
-    ["bezeichnung" => "West", "kurzbez" => "W", "winkel" => 247.5], +
-    ["bezeichnung" => "Nordwest", "kurzbez" => "NW", "winkel" => 292.5], +
-    ["bezeichnung" => "Nord", "kurzbez" => "N", "winkel" => 337.5], +
-); +
  
-function getWindrichtung($numDirection) { 
-    global $arrWindrichtung; 
-    $strBezeichnung=""; 
-    $strKurbez=""; 
-    foreach ($arrWindrichtung as $richtung) { 
-        if ($richtung['winkel'] <= $numDirection) { 
-            $strBezeichnung=$richtung['bezeichnung']; 
-            $strKurbez=$richtung['kurzbez']; 
-        } 
-    } 
-    return [$strBezeichnung,$strKurbez]; 
-} 
  
-?> +Das Projekt liegt auf Github zum Download bereit: https://github.com/wahu33/schule-suchen  
-</code>+
  
  
  • schule-suchen.1665341806.txt.gz
  • Zuletzt geändert: 09.10.2022 18:56
  • von whupfeld