Benutzer:Erik/Extension:Häfen in der Nähe: Unterschied zwischen den Versionen
Erik (Diskussion | Beiträge) →Installation: showdist Attribut zur konfiguartion der Anzeige der Distanz (An/Aus) hinzu gefügt |
Erik (Diskussion | Beiträge) Dokumentation und Revisionsliste aktualisiert. |
||
| Zeile 24: | Zeile 24: | ||
;lat:Angabe der geografischen Breit des Ausgsngspunkts | ;lat:Angabe der geografischen Breit des Ausgsngspunkts | ||
;dist:Der maximal Abstand vom Ausgangspunkt, den ein Hafen haben darf | ;dist:Der maximal Abstand vom Ausgangspunkt, den ein Hafen haben darf | ||
;showdist:Mit showdist="yes" wird die Anzeige der Distanzen aktiviert | |||
;max:Die maximale Anzahl von angezeigten Häfen | ;max:Die maximale Anzahl von angezeigten Häfen | ||
| Zeile 36: | Zeile 37: | ||
== Versionen == | == Versionen == | ||
;2007-03-04:Die Distanzanzeige ist nun per default deaktiviert. Sie kann über das Attribut showdist aktiviert werden. | |||
;2007-03-03:Fix für PHP4. Die benutzen DOM-Funktionen von PHP5 waren nicht rückwärtskompatibel. Die Umstellung auf DOM XML war zu aufwendig. Daher die 'saubere' Lösung: Erstellen eines Parsers. | ;2007-03-03:Fix für PHP4. Die benutzen DOM-Funktionen von PHP5 waren nicht rückwärtskompatibel. Die Umstellung auf DOM XML war zu aufwendig. Daher die 'saubere' Lösung: Erstellen eines Parsers. | ||
;2007-03-02:Initiale Version | ;2007-03-02:Initiale Version | ||
| Zeile 203: | Zeile 205: | ||
$max_cnt = 10; | $max_cnt = 10; | ||
} | } | ||
$show_distance = false; | $show_distance = false; | ||
if (isset($argv["showdist"])) { | if (isset($argv["showdist"])) { | ||
| Zeile 210: | Zeile 212: | ||
} | } | ||
} | } | ||
// initialize the array for the found places | // initialize the array for the found places | ||
$nearby_places = array(); | $nearby_places = array(); | ||
| Zeile 282: | Zeile 284: | ||
$cnt = 0; | $cnt = 0; | ||
foreach ($nearby_places as $place) { | foreach ($nearby_places as $place) { | ||
$output .= "[[" . $place["link"] . "|" . $place["name"] . "]]"; | $output .= "[[" . $place["link"] . "|" . $place["name"] . "]]"; | ||
if ($show_distance == true) { | if ($show_distance == true) { | ||
| Zeile 288: | Zeile 290: | ||
} | } | ||
$output .= " |\n"; | $output .= " |\n"; | ||
$cnt++; | $cnt++; | ||
if ($cnt >= $max_cnt) { | if ($cnt >= $max_cnt) { | ||
Version vom 5. März 2007, 08:43 Uhr
Hier befindet sich ein Vorschlag für eine Extension zur Anzeige von Häfen in der Nähe eines gebenen Punkts. Kommentare, Bugs und Verbesserungsvorschläge bitte auf der Diskussionsseite
Nach dem Erstellen der Navigationsleisten, habe ich überlegt, wie man sinnvolle Navigationsleisten auch automatisch erstellen kann. Eine Möglichkeit habe ich einmal in der folgenden Extension ausprobiert. Sie arbeitet als Parser Hook und listet alle Häfen in der Nähe einer gegebenen geografischen Position auf. Die Position, sowie die maximale Distanz und die maximale Anzahl der anzuzeigenden Häfen kann als Parameter übergeben werden. Die bekannten Häfen werden auf das Zutreffen der Bedingungen untersucht und dann nach Entfernung und Alphabet geordnet angezeigt. Die Extension greift auf das kml-File zurück, welches von der GoogleEarthExport Extension erzeugt wird.
Beispiel
Im folgenden ein Beispiel, wie man die Extension in Verbindung mit der Vorlage Navigationsleiste nutzen kann:
{{Navigationsleiste
|TITEL=Häfen in der Umgebung
|INHALT=
<nearbyplaces lat="54.333333" lon="10.133333" dist="100" max="10"/>
}}
Bedienung
Das Aufrufen der Orte geschieht mit dem Tag <nearbyplaces/> oder auch <nearbyplaces></nearbyplaces>. Ohne die Angabe weiterer Parameter werden die zehn am nächsten an Kiel gelegenen Häfen, die maximal 100sm von Kiel entfernt sein dürfen. Diese Darstellung kann durch die folgenden Parameter verändert werden:
- lon
- Angabe der geografischen Länge des Ausgangspunkts
- lat
- Angabe der geografischen Breit des Ausgsngspunkts
- dist
- Der maximal Abstand vom Ausgangspunkt, den ein Hafen haben darf
- showdist
- Mit showdist="yes" wird die Anzeige der Distanzen aktiviert
- max
- Die maximale Anzahl von angezeigten Häfen
Diese Werte werden als Attribute des Tags gesetzt. Beispiel:
<nearbyplaces lat="54.333333" lon="10.133333" dist="100" max="10"/>
Die Reihenfolge der Parameter ist dabei egal. Der Wert sollte immer in Anführungsstriche gesetzt sein. Wird ein Parameter ausgelassen, so wird der Default-Wert (s.o.) genommen.
Eine lauffähige Installation des Scripts gibt es hier. Dort kann auch mit den Einstellungen experimentiert werden.
Versionen
- 2007-03-04
- Die Distanzanzeige ist nun per default deaktiviert. Sie kann über das Attribut showdist aktiviert werden.
- 2007-03-03
- Fix für PHP4. Die benutzen DOM-Funktionen von PHP5 waren nicht rückwärtskompatibel. Die Umstellung auf DOM XML war zu aufwendig. Daher die 'saubere' Lösung: Erstellen eines Parsers.
- 2007-03-02
- Initiale Version
Installation
Das folgende Script (NearbyPlacesExtension.php) muss im Extensions-Verzeichnis abgelegt und die Zeile require_once("./extensions/NearbyPlacesExtension.php"); muss zu der LocalSettings.php hinzugefügt werden.
<?php
// HISTORY
// 2007-03-04 : The display of the distance is no deactivated by default.
// It can be activated using the showdist attribute.
// 2007-03-04 : Fix for PHP 4
// Instead of DOM or DOM XML, the xml parser functions are used
// 2007-03-02 : Initial implemtation
// TODO
// - debug output
// - testing
// - lat and lon in degrees and minutes
// - improved retrival of places
// - error handling
// - config file
// - documentation
// - output data to be selected by attributes
// - error handling
// register the extension
$wgExtensionFunctions[] = "wfNearbyPlacesExtension";
// set the credit information
$wgExtensionCredits['parserhook'][] = array(
'name' => 'Nearby Places',
'author' => 'Erik Hansen',
'url' => 'http://www.skipperguide.de/wiki/Benutzer:Erik/Extension:H%C3%A4fen_in_der_N%C3%A4he',
'description' => 'Shows a list of places near a given place',
);
// initialize this extension
// register nearbyplaces as parser hook.
function wfNearbyPlacesExtension() {
global $wgParser;
$wgParser->setHook( "nearbyplaces", "npeShowNearbyPlaces" );
}
// the comparation function for sorting the places array
// this sort all places first by distance then by their name
function npeCmpPlacesByDist($a, $b) {
if ($a["dist"] == $b["dist"]) {
return strcmp($a["name"], $b["name"]);
}
return ($a["dist"] < $b["dist"]) ? -1 : 1;
}
// XML Parser Class
class npeCParser {
var $places;
var $tag;
var $description;
var $placename;
var $coordinates;
var $parser;
// constructor
function npeCParser() {
$this->places = array();
$this->tag = "";
$this->description = "";
$this->placename = "";
$this->coordinates = "";
}
// initialize variables for every new placemark
// store the current tag for use within die characterData function
function startElement($parser, $name, $attrs) {
if ($name == "PLACEMARK") {
$this->description = "";
$this->placename = "";
$this->coordinates = "";
}
$this->tag = $name;
}
// store the data from the closed placemark
function endElement($parser, $name) {
if ($name == "PLACEMARK") {
$this->places[] = array ("name" => trim($this->placename),
"description" => trim($this->description),
"coordinates" => trim($this->coordinates));
}
}
// store the data of the tags
function characterData($parser, $data) {
switch ($this->tag) {
case "NAME":
$this->placename .= $data;
break;
case "DESCRIPTION":
$this->description .= $data;
break;
case "COORDINATES":
$this->coordinates .= $data;
break;
}
}
// parse the xml data
function parse($xml) {
$this->parser = xml_parser_create();
xml_set_object($this->parser, $this);
xml_parser_set_option($this->parser, XML_OPTION_SKIP_WHITE, 1);
xml_set_element_handler($this->parser, "startElement", "endElement");
xml_set_character_data_handler($this->parser, "characterData");
xml_parse($this->parser, $xml);
xml_parser_free($this->parser);
return $this->places;
}
}
// this function
function npeShowNearbyPlaces( $input, $argv, &$parser ) {
// this is needed to use wiki syntax in the output
global $wgOut;
// get the supplied arguments
if (isset($argv["lat"])) {
$req_lat = $argv["lat"];
} else {
$req_lat = 54.333333;
}
if (isset($argv["lon"])) {
$req_lon = $argv["lon"];
} else {
$req_lon = 10.133333;
}
if (isset($argv["dist"])) {
$max_dist = $argv["dist"];
} else {
$max_dist = 100;
}
if (isset($argv["max"])) {
$max_cnt = $argv["max"];
} else {
$max_cnt = 10;
}
$show_distance = false;
if (isset($argv["showdist"])) {
if ($argv["showdist"] == "yes") {
$show_distance = true;
}
}
// initialize the array for the found places
$nearby_places = array();
// create a new dom instance and load the kml file into it
$xml = file_get_contents("http://www.skipperguide.de/extension/GoogleEarthExport.php");
// create a new Parser and parse the retrieved kml file
$parser = new npeCParser();
$places = $parser->parse($xml);
// pick all placemarks from the kml-File
// In case none is found we are done already.
if (count($places) == 0)
return ("Es wurden leider keine Häfen gefunden (0).");
// parse through all palces from the kml file
foreach ($places as $place) {
list($lon, $lat) = sscanf($place["coordinates"], "%f,%f");
// in case the difference in nm between the latitudes is
// lager than the distance, we do not hat to proceed any
// further with this place
if (abs($lat - $req_lat) >> ($max_dist / 3600.0)) {
continue;
}
// calculate the distance between the two places
// this is done by calculating the loxodromic distance
// using the (Besteckrechnung nach Mittelbreite).
// This should be sufficient for distances shorter than
// 500nm.
// In case the distance is larger than max_dist,
// this place will be discarded.
$b = $lat - $req_lat;
$l = $lon - $req_lon;
$pm = ($lat + $req_lat) / 2;
$a = $l * cos($pm);
$al = atan ($a / $b);
$dist = abs(60 * $b / cos ($al));
if ($dist > $max_dist) {
continue;
}
// in case we have come that far, the place will be added
// to the list of places within the requested range
list($link) = sscanf($place["description"], "http://www.skipperguide.de/wiki/%s");
$nearby_places[] = array ("lat" => $lat,
"lon" => $lon,
"dist" => $dist,
"name" => $place["name"],
"link" => $link);
}
// check wether any places have been found.
if (count($nearby_places) == 0)
return ("Es wurden leider keine Häfen gefunden (1).");
// sort all places using npeCmpPlacesByDist for comparation
// this sorts all places by distance. Places with the same
// distancs are sorted by their name
usort($nearby_places, "npeCmpPlacesByDist");
// initialize the output string
$output = "";
// output all places up to max_cnt places ordered by distance an name
$cnt = 0;
foreach ($nearby_places as $place) {
$output .= "[[" . $place["link"] . "|" . $place["name"] . "]]";
if ($show_distance == true) {
$output .= " (" . number_format($place["dist"], 0) . "sm)";
}
$output .= " |\n";
$cnt++;
if ($cnt >= $max_cnt) {
break;
}
}
// parse the output with the wiki parser, then return the result
return ($wgOut->parse($output));
}
?>
ToDo
- Verbesserte Abfrage der Orte
- Bisher ruft das Script über http die KML-Datei des GoogleEarthExports ab. Da die Daten dafür allerdings ja auch auf dem Server liegen, ist es wohl besser direkt auf diese Daten zuzugreifen. Ist irgendwo dokumentiert, wie die Daten abgelegt sind?
- Parameter
- Die Usability bei den Parametern könnte deutlich erhöht werden:
- Lon und Lat in Grad und Minuten übergeben
- Plasibilitätstests auf die Parameter
- Test mit verschiedenen Wiki-Versionen
- Bisher wurde die Extension nur mit 1.6.0, 1.7.1, 1.9.3 getestet. Andere Versionen müssen noch getestet werden. Auch wurde bei den Tests nur PHP 5 verwendet. Läuft das Script auch mit PHP 4?
- Bisherige Testumgebungen:
- MediaWiki: 1.6.0, PHP: 5.1.2 (apache2handler), MySQL: 5.0.18
- MediaWiki: 1.7.1, PHP: 5.1.6 (cgi), MySQL: 4.0.24
- MediaWiki: 1.9.3, PHP: 5.1.6 (apache2handler), MySQL: 5.0.27-log (Läuft noch nicht. Statt des Texts erscheinen wirre Zeichen beginnend mit UINQ)
- Debugging
- Zum besseren Debuggen müssten Debug-Ausgaben eingebaut werden.
- Internationalisierung
- Die Bildschirmausgaben im Fehlerfall, sowie die 'sm' sollten internationalisiert werden. Entsprechende Übersetzungen müssten eingefügt werden.
- Config-File
- Bisher ist alles hart rein gecodet. Veränderliche Einstellungen (z.B. der Linkt zum Downloaden der KML-Datei) sollten über Variablen in der LocalConfig.php oder über eine eigene Config-Datei einstellbar sein.
- Dokumentation
- Wie immer könnte die besser sein ;)
- Fehlerbehandlungen
- Müssen noch hinzu gefügt werden. Sind bisher noch nicht vorhanden.
