X-Git-Url: https://git.toastfreeware.priv.at/philipp/winterrodeln/mediawiki_extensions/wrmap.git/blobdiff_plain/3a0377b6a3297951b5d023367bb00a42ce89ea0c..1234fddc62ff7e34d1b5b7d2f5f613fc18e45ef1:/wrmap.body.php diff --git a/wrmap.body.php b/wrmap.body.php index 059eab5..7fc7265 100644 --- a/wrmap.body.php +++ b/wrmap.body.php @@ -1,4 +1,162 @@ + +(Shows icons for all sledruns. lat, lon and zoom are optional.) + + +Example 2 +--------- + + + +47.240689 11.190454 +47.238186 11.221940 +47.240287 11.203006 +47.245789 11.238971 +47.237627 11.218886 +47.245711 11.238283 +47.2383200 11.2235592 + + +47.238587 11.203360 +47.239743 11.203522 +47.240135 11.203247 + + + +47.238442 11.203263 +47.237799 11.203511 +47.237133 11.202988 +47.238091 11.206642 +47.237273 11.211675 +47.237133 11.214466 +47.237513 11.218199 + + + +47.240487 11.190169 +47.238996 11.188628 +47.238987 11.188018 +47.238267 11.187075 +47.238461 11.190511 +47.239751 11.191795 +47.240037 11.192702 +47.239525 11.193535 +47.239688 11.194272 +47.239017 11.193925 +47.239536 11.195457 +47.240063 11.196230 +47.240747 11.196658 +47.239734 11.198295 +47.238857 11.198346 +47.237743 11.199778 +47.238250 11.202755 +47.238587 11.203360 + + + +47.238587 11.203360 +47.238185 11.203982 +47.238297 11.204381 +47.239417 11.204972 +47.239210 11.208772 +47.238999 11.209523 +47.239126 11.209839 +47.238933 11.210641 +47.239102 11.210739 +47.238666 11.215042 +47.238203 11.216089 +47.238183 11.218151 +47.237851 11.218599 +47.238055 11.219755 +47.237686 11.222441 +47.238000 11.223367 +47.238625 11.223687 +47.239915 11.223118 +47.240992 11.219781 +47.243412 11.214141 +47.243207 11.218331 +47.243990 11.216205 +47.243785 11.223251 +47.242845 11.228510 +47.242917 11.232501 +47.242524 11.235001 +47.244737 11.231791 +47.244951 11.230868 +47.245470 11.237853 + + + +47.245656 11.237286 +47.238189 11.221344 + + + + + + +Definition +---------- + +* ... has to be valid XML. +* All coordinates are in WGS84 coordinate system. +* Coordinates have the preferred format "latitude N longitude E", + however for parsing the N and E can be omitted. +* has the following attributes: + * lat (float): latitude of map-center, optional. + * lon (float): longitude of map-center, optional. + * zoom (integer): zoom level of the map (google zoom levels). optional. + * width (integer): width of the map in pixel. optional (100% if omitted) + * height (integer): height of the map in pixel. optional. + * can have any number of the following sub-elements: + * + * + * + * + * + * + * + * + * + * + * + * + * + * The order may be used by the renderer to determine in which order the + elements should be drawn. +* , , , , , and define points + * The elements may have the following attributes: + * name (string): defines the name (not the label) of the element + * wiki (string): name of a MediaWiki page the point refers to + * The content is exactly one coordinate pair. +* , , , , and + define non-closed polygons. + * They may have the following attributes: + farbe (hex format, e.g. #12a50f): color of the line + dicke (int): width of the line in pixel + * The content of the elements are a whitespace separated list of + coordinates. + + +For transmitting the map to javascript, geojson is used in the
element of the map. +This way, an extra request is avoided. The geojson format used here consists of a single +"FeatureCollection" (representing the ) containing the sub-elements of wrmap +as features. +The features have an properties key that has a hash as values with the properties of +the XML subelements of wrmap. Optional attributes/properties can be omitted. +Additionally one mandatory property key is called 'type' and has the sub-element's name +as value. +The featurecollection itself has a properties key as well containing the attributes of +the wrmap element. +*/ + // DOM helper classes // ------------------ @@ -67,11 +225,49 @@ class WrBaseMap { for ($i=0; $i!=$num_matches; ++$i) { $result[] = array(floatval($matches[2][$i]), floatval($matches[1][$i])); } - if (implode($matches[0]) != $input) throw new Exception('Falsches Koordinatenformat: ' . $input); + if (implode($matches[0]) != $input) throw new Exception(wfMessage('wrmap-error-coordinate-format', $input)->text()); return $result; } + /// Takes a page title from the wiki and returns an image (if available) + /// or Null. For image wiki pages, the image is the corresponding image, + /// for inns it's the image of the "Gasthausbox". + public static function wikipage_to_image($title, $width) { + $file = false; // File class or false + // for NS_FILE titles, use the corresponding file as image + if ($title->getNamespace() == NS_FILE) { + $file = wfFindFile($title); // $file is a mediawiki File class or false + } else { + $categories = $title->getParentCategories(); // e.g. array('Kategorie:Rodelbahn' => 'Juifenalm') + global $wgContLang; + $key_sledrun = $wgContLang->getNSText(NS_CATEGORY) . ':Rodelbahn'; + if (array_key_exists($key_sledrun, $categories)) { + // for sledrun titles use the image from the rodelbahnbox + $dbr = wfGetDB(DB_SLAVE); + $res = $dbr->select('wrsledruncache', 'image', array('page_id' => $title->getArticleID()), __METHOD__); + $image = $dbr->fetchRow($res); + if ($image && !is_null($image['image'])) $file = wfFindFile($image['image']); + $dbr->freeResult($res); + } + $key_inn = $wgContLang->getNSText(NS_CATEGORY) . ':Gasthaus'; + if (array_key_exists($key_inn, $categories)) { + // for inn titles use the image from the gasthausbox + $dbr = wfGetDB(DB_SLAVE); + $res = $dbr->select('wrinncache', 'image', array('page_id' => $title->getArticleID()), __METHOD__); + $image = $dbr->fetchRow($res); + if ($image && !is_null($image['image'])) $file = wfFindFile($image['image']); + $dbr->freeResult($res); + } + } + if ($file === false) return Null; + if (!$file->canRender()) return Null; + $thumb_url = $file->createThumb($width, $width); // limit width and hight to $width + if (strlen($thumb_url) == 0) return Null; + return $thumb_url; + } + + // convert sledruns to geojson (http://www.geojson.org/geojson-spec.html) // Returns an array of features public static function sledruns_to_json_features() { @@ -88,8 +284,10 @@ class WrBaseMap { $properties = array('type' => 'sledrun', 'name' => $title->getText(), 'wiki' => $title->getLocalUrl()); if (!is_null($sledrun['date_report'])) $properties['date_report'] = $sledrun['date_report']; if (!is_null($sledrun['condition'])) $properties['condition'] = intval($sledrun['condition']); + $image_url = WrBaseMap::wikipage_to_image($title, 150); + if (!is_null($image_url)) $properties['thumb_url'] = $image_url; $json_feature = array( - 'type' => 'feature', + 'type' => 'Feature', 'geometry' => array( 'type' => 'Point', 'coordinates' => array($lon, $lat) @@ -110,10 +308,10 @@ class WrBaseMap { $xml = new SimpleXMLElement($input); // input $whitespace = (string) $xml; // everything between and that's not a sub-element if (strlen($whitespace) > 0 && !ctype_space($whitespace)) { // there must not be anythin except sub-elements or whitespace - throw new Exception('Die Landkarte enthält folgenden ungültigen Text: "' . trim($xml) . '".'); + throw new Exception(wfMessage('wrmap-error-invalid-text', trim($xml))->text()); } $json_features = array(); // output - $point_types = array('gasthaus', 'haltestelle', 'parkplatz', 'achtung', 'foto', 'punkt'); + $point_types = array('gasthaus', 'haltestelle', 'parkplatz', 'achtung', 'foto', 'verleih', 'punkt'); $line_types = array('rodelbahn', 'gehweg', 'alternative', 'lift', 'anfahrt', 'linie'); foreach ($xml as $feature) { $given_properties = array(); @@ -123,7 +321,7 @@ class WrBaseMap { $is_point = in_array($feature->getName(), $point_types); $is_line = in_array($feature->getName(), $line_types); if (!$is_point && !$is_line) { - throw new Exception('Unbekanntes Element <' . $feature->getName() . '>. Erlaubt sind: <' . implode('>, <', array_merge($point_types, $line_types)) . '>.'); + throw new Exception(wfMessage('wrmap-error-invalid-element', $feature->getName(), '<' . implode('>, <', array_merge($point_types, $line_types)) . '>')->text()); } // point @@ -131,19 +329,21 @@ class WrBaseMap { $properties = array('type' => $feature->getName()); $allowed_properties = array('name', 'wiki'); $wrong_properties = array_diff($given_properties, $allowed_properties); - if (count($wrong_properties) > 0) throw new Exception("Das Attribut '" . reset($wrong_properties) . "' ist nicht erlaubt bei <" . $feature->getName() . ">. Erlaubt sind: '" . implode("', '", $allowed_properties) . "'."); + if (count($wrong_properties) > 0) throw new Exception(wfMessage('wrmap-error-invalid-attribute', reset($wrong_properties), $feature->getName(), "'" . implode("', '", $allowed_properties) . "'")->text()); foreach ($given_properties as $property) { $propval = (string) $feature[$property]; if ($property == 'wiki') { $title = Title::newFromText($propval); $propval = $title->getLocalUrl(); + $file_url = WrBaseMap::wikipage_to_image($title, 200); + if (!is_null($file_url)) $properties['thumb_url'] = $file_url; } $properties[$property] = $propval; } $coordinates = WrBaseMap::geo_to_coordinates($feature); - if (count($coordinates) != 1) throw new Exception('Das Element <' . $feature->getName() . '> muss genau ein Koordinatenpaar haben.'); + if (count($coordinates) != 1) throw new Exception(wfMessage('wrmap-error-coordinate-count', $feature->getName())->text()); $json_feature = array( - 'type' => 'feature', + 'type' => 'Feature', 'geometry' => array( 'type' => 'Point', 'coordinates' => reset($coordinates) @@ -157,21 +357,21 @@ class WrBaseMap { $properties = array('type' => $feature->getName()); $allowed_properties = array('farbe', 'dicke'); $wrong_properties = array_diff($given_properties, $allowed_properties); - if (count($wrong_properties) > 0) throw new Exception("Das Attribut '" . reset($wrong_properties) . "' ist nicht erlaubt bei <" . $feature->getName() . ">. Erlaubt sind: '" . implode("', '", $allowed_properties) . "'."); + if (count($wrong_properties) > 0) throw new Exception(wfMessage('wrmap-error-invalid-attribute', reset($wrong_properties), $feature->getName(), "'" . implode("', '", $allowed_properties) . "'")->text()); if (isset($feature['farbe'])) { $color = (string) $feature['farbe']; // e.g. #a200b7 - if (preg_match('/^#[0-9a-f]{6}$/i', $color) != 1) - throw new Exception('Die Farbangabe der Linie hat ein falsches Format. Sie muss z.B. so aussehen: #a200b7.'); + if (preg_match('/^#[0-9a-f]{6}$/i', $color) != 1) + throw new Exception(wfMessage('wrmap-error-line-color')->text()); $properties['strokeColor'] = $color; } if (isset($feature['dicke'])) { $stroke_width = (int) $feature['dicke']; // e.g. 6 if (((string) $stroke_width) !== (string) $feature['dicke']) - throw new Exception('Die Angabe der Liniendicke hat ein falsches Format. Sie muss eine ganze Zahl wie z.B. 6 sein.'); + throw new Exception(wfMessage('wrmap-error-line-width')->text()); $properties['strokeWidth'] = $stroke_width; } $json_feature = array( - 'type' => 'feature', + 'type' => 'Feature', 'geometry' => array( 'type' => 'LineString', 'coordinates' => WrBaseMap::geo_to_coordinates($feature) @@ -199,7 +399,8 @@ class WrBaseMap { assert(in_array($tagname, array('wrmap', 'wrgmap'))); $parserOutput = $parser->getOutput(); - $parserOutput->addHeadItem('', 'googlemaps'); + $parserOutput->addHeadItem('', 'openlayers_js'); + $parserOutput->addHeadItem('', 'openlayers_css'); $parserOutput->addModules('ext.wrmap'); // append all sledruns as icon @@ -237,23 +438,41 @@ class WrBaseMap { // Create
element where the map is placed in global $wgExtensionAssetsPath; $doc = new WrMapDOMDocument(); - $div = $doc->appendElement('div', array('class' => 'wrmap', 'style' => 'border-style:none;', 'data-img-path' => "$wgExtensionAssetsPath/wrmap/openlayers/img/")); + $div_map = $doc->appendElement('div', array('class' => 'wrmap', 'style' => 'border-style:none;', 'data-ext-path' => "$wgExtensionAssetsPath/wrmap")); // progress message - $div->appendElement('div', array())->appendText('Die Landkarte wird geladen...'); + $div_map->appendElement('div', array())->appendText(wfMessage('wrmap-loading')->text()); // data - $div->appendElement('div', array('style' => 'height: 0px; display:none;'))->appendText($json_string); - return array($doc->saveHTML($div), 'markerType' => 'nowiki'); + $div_map->appendElement('div', array('style' => 'height: 0px; display:none;'))->appendText($json_string); + // popup + $div_popup = $doc->appendElement('div', array('id' => 'popup', 'class' => 'ol-popup')); + $div_popup->appendElement('a', array('id' => 'popup-closer', 'href' => '#', 'class' => 'ol-popup-closer')); + $div_popup->appendElement('div', array('id' => 'popup-content')); + return array($doc->saveHTML($div_map) . $doc->saveHTML($div_popup), 'markerType' => 'nowiki'); + } + + + public static function onEnableMobileModules($out, $mode) { + $out->addModules('ext.wrmap.mobile'); + return true; } } // tag class WrMap extends WrBaseMap { + public static function onParserFirstCallInit(Parser $parser) { + $parser->setHook('wrmap', 'WrMap::render'); + return true; + } } // tag class WrGMap extends WrBaseMap { + public static function onParserFirstCallInit(Parser $parser) { + $parser->setHook('wrgmap', 'WrGMap::render'); + return true; + } } ?>