r52343 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r52342‎ | r52343 | r52344 >
Date:03:51, 24 June 2009
Author:aude
Status:resolved (Comments)
Tags:
Comment:
new code, split into class files
Modified paths:
  • /trunk/extensions/SlippyMap/SlippyMap.alias.php (added) (history)
  • /trunk/extensions/SlippyMap/SlippyMap.class.php (modified) (history)
  • /trunk/extensions/SlippyMap/SlippyMap.css (added) (history)
  • /trunk/extensions/SlippyMap/SlippyMap.hooks.php (added) (history)
  • /trunk/extensions/SlippyMap/SlippyMap.i18n.php (modified) (history)
  • /trunk/extensions/SlippyMap/SlippyMap.js (added) (history)
  • /trunk/extensions/SlippyMap/SlippyMap.php (modified) (history)
  • /trunk/extensions/SlippyMap/SlippyMap.worldwind.php (added) (history)

Diff [purge]

Index: trunk/extensions/SlippyMap/SlippyMap.i18n.php
@@ -56,6 +56,8 @@
5757 'slippymap_button_code' => 'Get wikicode',
5858 'slippymap_resetview' => 'Reset view',
5959 'slippymap_license' => 'OpenStreetMap - CC-BY-SA-2.0', # do not translate or duplicate this message to other languages
 60+ 'slippymap_invalidmode' => "Invalid 'mode' value '$1'",
 61+ 'slippymap_clicktoactivate' => 'Click to activate map'
6062 );
6163
6264 /** Message documentation (Message documentation)
Index: trunk/extensions/SlippyMap/SlippyMap.php
@@ -1,74 +1,82 @@
2 -<?php
3 -# OpenStreetMap SlippyMap - MediaWiki extension
4 -#
5 -# This defines what happens when <slippymap> tag is placed in the wikitext
6 -#
7 -# We show a map based on the lat/lon/zoom data passed in. This extension brings in
8 -# the OpenLayers javascript, to show a slippy map.
9 -#
10 -# Usage example:
11 -# <slippymap lat=51.485 lon=-0.15 z=11 w=300 h=200 layer=osmarender></slippymap>
12 -#
13 -# Tile images are not cached local to the wiki.
14 -# To acheive this (remove the OSM dependency) you might set up a squid proxy,
15 -# and modify the requests URLs here accordingly.
16 -#
17 -# This file should be placed in the mediawiki 'extensions' directory
18 -# ...and then it needs to be 'included' within LocalSettings.php
19 -#
20 -# #################################################################################
21 -#
22 -# Copyright 2008 Harry Wood, Jens Frank, Grant Slater, Raymond Spekking and others
23 -#
24 -# This program is free software; you can redistribute it and/or modify
25 -# it under the terms of the GNU General Public License as published by
26 -# the Free Software Foundation; either version 2 of the License, or
27 -# (at your option) any later version.
28 -#
29 -# This program is distributed in the hope that it will be useful,
30 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
31 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 -# GNU General Public License for more details.
33 -#
34 -# You should have received a copy of the GNU General Public License
35 -# along with this program; if not, write to the Free Software
36 -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 -#
38 -# @addtogroup Extensions
39 -#
 2+<?php
 3+/**
 4+* @file
 5+*
 6+* @section DESCRIPTION
 7+*
 8+* OpenStreetMap SlippyMap - MediaWiki extension
 9+*
 10+* This defines what happens when <slippymap> tag is placed in the wikitext
 11+*
 12+* We show a map based on the lat/lon/zoom data passed in. This extension brings in
 13+* the OpenLayers javascript, to show a slippy map.
 14+*
 15+* Usage example:
 16+* <slippymap lat=51.485 lon=-0.15 z=11 w=300 h=200 layer=osmarender></slippymap>
 17+*
 18+* Tile images are not cached local to the wiki.
 19+* To acheive this (remove the OSM dependency) you might set up a squid proxy,
 20+* and modify the requests URLs here accordingly.
 21+*
 22+* This file should be placed in the mediawiki 'extensions' directory
 23+* ...and then it needs to be 'included' within LocalSettings.php
 24+*
 25+* @section LICENSE
 26+*
 27+* Copyright 2008 Harry Wood, Jens Frank, Grant Slater, Raymond Spekking and others
 28+*
 29+* This program is free software; you can redistribute it and/or modify
 30+* it under the terms of the GNU General Public License as published by
 31+* the Free Software Foundation; either version 2 of the License, or
 32+* (at your option) any later version.
 33+*
 34+* This program is distributed in the hope that it will be useful,
 35+* but WITHOUT ANY WARRANTY; without even the implied warranty of
 36+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 37+* GNU General Public License for more details.
 38+*
 39+* You should have received a copy of the GNU General Public License
 40+* along with this program; if not, write to the Free Software
 41+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 42+*
 43+*/
4044
41 -
 45+/**
 46+ * Checks if the file is being executed within MediaWiki
 47+ */
4248 if ( !defined( 'MEDIAWIKI' ) )
43 - die();
 49+ die();
4450
45 -if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
46 - $wgHooks['ParserFirstCallInit'][] = 'wfslippymap';
47 -} else {
48 - $wgExtensionFunctions[] = 'wfslippymap';
49 -}
5051
 52+/**
 53+* Property: Extension credits
 54+*/
5155 $wgExtensionCredits['parserhook'][] = array(
52 - 'path' => __FILE__,
53 - 'name' => 'OpenStreetMap Slippy Map',
54 - 'author' => array( '[http://harrywood.co.uk Harry Wood]', 'Jens Frank' ),
55 - 'url' => 'http://wiki.openstreetmap.org/index.php/Slippy_Map_MediaWiki_Extension',
56 - 'description' => 'Allows the use of the &lt;slippymap&gt; tag to display an OpenLayers slippy map. Maps are from [http://openstreetmap.org openstreetmap.org]',
57 - 'descriptionmsg' => 'slippymap_desc',
 56+ 'name' => 'OpenStreetMap Slippy Map',
 57+ 'author' => array( '[http://harrywood.co.uk Harry Wood]', 'Jens Frank' ),
 58+ 'url' => 'http://wiki.openstreetmap.org/index.php/Slippy_Map_MediaWiki_Extension',
 59+ 'description' => 'Allows the use of the &lt;slippymap&gt; tag to display an OpenLayers slippy map. Maps are from [http://openstreetmap.org openstreetmap.org]',
 60+ 'descriptionmsg' => 'slippymap_desc',
5861 );
5962
6063 $dir = dirname( __FILE__ ) . '/';
61 -$wgAutoloadClasses['SlippyMap'] = $dir . 'SlippyMap.class.php';
 64+
 65+$wgMapModes = array( 'osm', 'satellite' );
 66+
 67+$wgAutoLoadMaps = false;
 68+
6269 $wgExtensionMessagesFiles['SlippyMap'] = $dir . 'SlippyMap.i18n.php';
 70+$wgExtensionAliasesFiles['SlippyMap'] = $dir . 'SlippyMap.alias.php';
6371
64 -function wfslippymap() {
65 - global $wgParser, $wgHooks, $wgMapOfServiceUrl;
66 - # register the extension with the WikiText parser
67 - # the first parameter is the name of the new tag.
68 - # In this case it defines the tag <slippymap> ... </slippymap>
69 - # the second parameter is the callback function for
70 - # processing the text between the tags
71 - $wgParser->setHook( 'slippymap', array( 'SlippyMap', 'parse' ) );
72 - $wgHooks['ParserAfterTidy'][] = 'SlippyMap::ParserAfterTidy';
73 - $wgMapOfServiceUrl = "http://osm-tah-cache.firefishy.com/~ojw/MapOf/?";
74 - return true;
 72+$wgAutoloadClasses['SlippyMapHooks'] = $dir . 'SlippyMap.hooks.php';
 73+$wgAutoloadClasses['SlippyMap'] = $dir . 'SlippyMap.class.php';
 74+$wgAutoloadClasses['WorldWind'] = $dir . 'SlippyMap.worldwind.php';
 75+
 76+if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
 77+ $wgHooks['ParserFirstCallInit'][] = 'SlippyMapHooks::onParserFirstCallInit';
 78+} else {
 79+ $wgExtensionFunctions[] = 'SlippyMapHooks::onParserFirstCallInit';
7580 }
 81+
 82+$wgHooks['ParserAfterTidy'][] = 'SlippyMapHooks::wfSlippyMapParserAfterTidy';
 83+
Index: trunk/extensions/SlippyMap/SlippyMap.css
@@ -0,0 +1,61 @@
 2+.mapframe {
 3+ position:relative;
 4+ padding:.7em;
 5+ color:#191970;
 6+ float:right;
 7+ border:solid 1px #cccccc;
 8+}
 9+
 10+.map {
 11+ position:relative;
 12+ border:solid 1px #000000;
 13+ float:right;
 14+ clear:right;
 15+ width: 100%;
 16+}
 17+
 18+.mapPreview {
 19+ cursor: pointer;
 20+ border: none;
 21+}
 22+
 23+.mapcaption {
 24+ position:relative;
 25+ clear:right;
 26+ float:right;
 27+ width: 100%;
 28+}
 29+
 30+/*
 31+ * Force override of delay-loaded styles from openlayers/theme/default/style.css
 32+ * TODO In the long run, we should probably create a MediaWiki theme
 33+ * that contains customizations
 34+ */
 35+.olControlAttribution {
 36+ right: 5px !important;
 37+ bottom: 0px !important;
 38+}
 39+
 40+/* Custom wikiCode and reset buttons */
 41+.buttonsPanel div {
 42+ float:left;
 43+ display:block;
 44+ position:relative;
 45+ left:50px;
 46+ margin-left:3px;
 47+ margin-top:7px;
 48+ width:36px;
 49+ height:19px;
 50+}
 51+
 52+.buttonsPanel .getWikiCodeButtonItemInactive {
 53+ width:36px;
 54+ height:19px;
 55+ background-image:url('wikicode-button.png');
 56+}
 57+
 58+.buttonsPanel .resetButtonItemInactive {
 59+ width:36px;
 60+ height:19px;
 61+ background-image:url('reset-button.png');
 62+}
\ No newline at end of file
Property changes on: trunk/extensions/SlippyMap/SlippyMap.css
___________________________________________________________________
Name: svn:eol-style
163 + native
Index: trunk/extensions/SlippyMap/SlippyMap.hooks.php
@@ -0,0 +1,172 @@
 2+<?php
 3+if ( ! defined( 'MEDIAWIKI' ) )
 4+ die();
 5+
 6+class SlippyMapHooks {
 7+
 8+ var $mapId;
 9+
 10+ /**
 11+ * Property: SlippyMapMarkerList
 12+ * Evil hack as documented at
 13+ * http://www.mediawiki.org/wiki/Manual:Tag_extensions#How_can_I_avoid_modification_of_my_extension.27s_HTML_output.3F
 14+ * This is here so that random <p> and <pre> tags aren't added to the inline JavaScript output
 15+ */
 16+ var $SlippyMapMarkerList = array();
 17+
 18+ /**
 19+ * Search string used to check for SlippyMap invocation
 20+ */
 21+ protected static $WIKITEXT_PATTERN = "slippymap";
 22+
 23+ public function __construct() {
 24+ $this->mapId = 0;
 25+ }
 26+
 27+ /**
 28+ * Sets up the slippy map and links JavaScript files
 29+ *
 30+ * Register the extension with the WikiText parser
 31+ * the first parameter is the name of the new tag.
 32+ * In this case it defines the tag <slippymap> ... </slippymap>
 33+ * the second parameter is the callback function for
 34+ * processing the text between the tags
 35+ *
 36+ * @return true
 37+ */
 38+
 39+ public function onParserFirstCallInit( ) {
 40+ global $wgArticle, $wgOut, $wgParser, $wgScriptPath, $wgJsMimeType, $wgStyleVersion, $wgAutoLoadMaps;
 41+
 42+ $smh = new SlippyMapHooks();
 43+
 44+ /**
 45+ * If not a special page ( $wgArticle exists ),
 46+ * then check for slippymap tag and
 47+ * add openlayers if page includes slippymap
 48+ * otherwise, do not add slippymap and openlayers js
 49+ * where unnecessary and will slow page load time.
 50+ */
 51+ if ( isset( $wgArticle ) && strstr($wgArticle->getRawText(), SlippyMapHooks::$WIKITEXT_PATTERN ) ) {
 52+
 53+ wfLoadExtensionMessages( 'SlippyMap' );
 54+
 55+ if ( $wgAutoLoadMaps ) {
 56+ $autoload = 'true';
 57+ } else {
 58+ $autoload = 'false';
 59+ }
 60+
 61+ $script = array(
 62+ "<script type=\"$wgJsMimeType\">/*<![CDATA[*/",
 63+ "var wgSlippyMapCode = " . Xml::encodeJsVar( wfMsg( 'slippymap_code' ) ) . ";",
 64+ "var wgSlippyMapButtonCode = " . Xml::encodeJsVar( wfMsg( 'slippymap_button_code' ) ) . ";",
 65+ "var wgSlippyMapResetview = " . Xml::encodeJsVar( wfMsg( 'slippymap_resetview' ) ) . ";",
 66+ "var autoInitMaps = {$autoload};",
 67+ "/*]]>*/</script>",
 68+ );
 69+
 70+ $wgOut->addScript( implode( "\n\t\t", $script ) . "\n" );
 71+ $wgOut->addScript( "<script type='$wgJsMimeType' src='" . $wgScriptPath . "/extensions/SlippyMap/openlayers/lib/OpenLayers.js?{$wgStyleVersion}'></script>" );
 72+ $wgOut->addScript( "<script type='$wgJsMimeType' src='" . $wgScriptPath . "/extensions/SlippyMap/SlippyMap.js?{$wgStyleVersion}'></script>" );
 73+ $wgOut->addLink( array( 'rel' => 'stylesheet','type' => 'text/css','href' => $wgScriptPath . '/extensions/SlippyMap/SlippyMap.css' ) );
 74+
 75+ $wgParser->setHook( 'slippymap', array( $smh, 'wfParseMapAttributes' ) );
 76+ }
 77+
 78+ return true;
 79+ }
 80+
 81+ public function wfParseMapAttributes( $input, $argv, $parser )
 82+ {
 83+ global $wgOut, $SlippyMapMarkerList, $wgMapModes;
 84+
 85+ /**
 86+ * Support old style parameters from $input
 87+ * Parse the pipe separated name value pairs (e.g. 'aaa=bbb|ccc=ddd')
 88+ * With the new syntax we expect nothing in the $input, so this will result in '' values
 89+ */
 90+
 91+ $oldStyleParamStrings = explode( '|', $input );
 92+ foreach ( $oldStyleParamStrings as $oldStyleParamString ) {
 93+ $oldStyleParamString = trim( $oldStyleParamString );
 94+ $eqPos = strpos( $oldStyleParamString, "=" );
 95+ if ( $eqPos === false ) {
 96+ $oldStyleParams[$oldStyleParamString] = 'true';
 97+ } else {
 98+ $oldStyleParams[substr( $oldStyleParamString, 0, $eqPos )] = trim( htmlspecialchars( substr( $oldStyleParamString, $eqPos + 1 ) ) );
 99+ }
 100+ }
 101+
 102+ foreach ( $argv as $key=>$val ) {
 103+ // Receive new style args: <slippymap aaa=bbb ccc=ddd></slippymap>
 104+ if ( isset( $val ) ) {
 105+ $key = strtolower( $key );
 106+ $mapParams[$key] = $val;
 107+ }
 108+ }
 109+
 110+ /**
 111+ * If using old style params, turn them into a mapParams array
 112+ */
 113+ if ( ( count( $mapParams ) == 0 ) && ( count( $oldStyleParams ) > 0 ) ) {
 114+ foreach ( $oldStyleParams as $key => $val ) {
 115+ // Receive new style args: <slippymap aaa=bbb ccc=ddd></slippymap>
 116+ if ( isset( $val ) ) {
 117+ $key = strtolower( $key );
 118+ $mapParams[$key] =& $val;
 119+ }
 120+ }
 121+ }
 122+
 123+ /**
 124+ * Give the map a unique id, so there can be multiple maps
 125+ */
 126+ $mapParams['mapId'] = $this->mapId;
 127+
 128+ if ( ! in_array( $mapParams['mode'], $wgMapModes ) ) {
 129+ $errors = wfMsg( 'slippymap_invalidmode', htmlspecialchars( $this->mode ) );
 130+ $wgOut->addHTML( '<h3>' . $mapParams['mode'] . ' is an invalid map mode</h3>' );
 131+ } else {
 132+ $output = '';
 133+ switch ( $mapParams['mode'] ) {
 134+ case 'satellite':
 135+ $map = new WorldWind( $mapParams );
 136+ break;
 137+ default:
 138+ $map = new SlippyMap( $mapParams );
 139+ }
 140+
 141+ $output .= $map->getMap( );
 142+ $this->mapId++;
 143+ $markercount = count( $SlippyMapMarkerList );
 144+ $pMarker = "SlippyMap-marker".$markercount."-SlippyMap";
 145+ $SlippyMapMarkerList[$markercount] = $output;
 146+ return $pMarker;
 147+
 148+ }
 149+
 150+ }
 151+
 152+ /**
 153+ * Evil hack
 154+ * @see http://www.mediawiki.org/wiki/Manual:Tag_extensions#How_can_I_avoid_modification_of_my_extension.27s_HTML_output.3F
 155+ */
 156+ function wfSlippyMapParserAfterTidy( &$parser, &$text ) {
 157+ global $SlippyMapMarkerList;
 158+ $keys = array();
 159+ $marker_count = count( $SlippyMapMarkerList );
 160+
 161+ for ($i = 0; $i < $marker_count; $i++) {
 162+ $keys[] = 'SlippyMap-marker' . $i . '-SlippyMap';
 163+ }
 164+
 165+ $text = str_replace( $keys, $SlippyMapMarkerList, $text );
 166+ return true;
 167+ }
 168+
 169+ function error( $msg ) {
 170+ $error = '<strong class="error">' . $msg . '</strong>';
 171+ return $error;
 172+ }
 173+}
Property changes on: trunk/extensions/SlippyMap/SlippyMap.hooks.php
___________________________________________________________________
Name: svn:eol-style
1174 + native
Name: svn:executable
2175 + *
Index: trunk/extensions/SlippyMap/SlippyMap.class.php
@@ -1,375 +1,450 @@
22 <?php
3 -# OpenStreetMap SlippyMap - MediaWiki extension
4 -#
5 -# This defines what happens when <slippymap> tag is placed in the wikitext
6 -#
7 -# We show a map based on the lat/lon/zoom data passed in. This extension brings in
8 -# the OpenLayers javascript, to show a slippy map.
9 -#
10 -# Usage example:
11 -# <slippymap lat="51.485" lon="-0.15" z="11" w="300" h="200" layer="osmarender" marker="0" />
12 -#
13 -# Tile images are not cached local to the wiki.
14 -# To acheive this (remove the OSM dependency) you might set up a squid proxy,
15 -# and modify the requests URLs here accordingly.
16 -#
17 -# This file should be placed in the mediawiki 'extensions' directory
18 -# ...and then it needs to be 'included' within LocalSettings.php
19 -#
20 -# #################################################################################
21 -#
22 -# Copyright 2008 Harry Wood, Jens Frank, Grant Slater, Raymond Spekking and others
23 -#
24 -# This program is free software; you can redistribute it and/or modify
25 -# it under the terms of the GNU General Public License as published by
26 -# the Free Software Foundation; either version 2 of the License, or
27 -# (at your option) any later version.
28 -#
29 -# This program is distributed in the hope that it will be useful,
30 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
31 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 -# GNU General Public License for more details.
33 -#
34 -# You should have received a copy of the GNU General Public License
35 -# along with this program; if not, write to the Free Software
36 -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 -#
38 -# @addtogroup Extensions
39 -#
 3+/**
 4+*
 5+* @file
 6+*
 7+* @description
 8+* OpenStreetMap SlippyMap - MediaWiki extension
 9+*
 10+* This defines what happens when <slippymap> tag is placed in the wikitext
 11+*
 12+* We show a map based on the lat/lon/zoom data passed in. This extension brings in
 13+* the OpenLayers javascript, to show a slippy map.
 14+*
 15+* Usage example:
 16+* <slippymap lat="51.485" lon="-0.15" z="11" w="300" h="200" layer="osmarender" marker="0" />
 17+*
 18+* Tile images are not cached local to the wiki.
 19+* To acheive this (remove the OSM dependency) you might set up a squid proxy,
 20+* and modify the requests URLs here accordingly.
 21+*
 22+* This file should be placed in the mediawiki 'extensions' directory
 23+* ...and then it needs to be 'included' within LocalSettings.php
 24+*
 25+* @license
 26+*
 27+* Copyright 2008 Harry Wood, Jens Frank, Grant Slater, Raymond Spekking and others
 28+*
 29+* This program is free software; you can redistribute it and/or modify
 30+* it under the terms of the GNU General Public License as published by
 31+* the Free Software Foundation; either version 2 of the License, or
 32+* (at your option) any later version.
 33+*
 34+* This program is distributed in the hope that it will be useful,
 35+* but WITHOUT ANY WARRANTY; without even the implied warranty of
 36+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 37+* GNU General Public License for more details.
 38+*
 39+* You should have received a copy of the GNU General Public License
 40+* along with this program; if not, write to the Free Software
 41+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 42+*
 43+*/
4044
41 -# Evil hack as documented at
42 -# http://www.mediawiki.org/wiki/Manual:Tag_extensions#How_can_I_avoid_modification_of_my_extension.27s_HTML_output.3F
43 -# This is here so that random <p> and <pre> tags aren't added to the inline JavaScript output
44 -$SlippyMapMarkerList = array( );
 45+class SlippyMap {
4546
46 -# The number of Slippy Maps we have had thus far, to get unique JavaScript variables
47 -$SlippyMapCounter = 1;
48 -
49 -class SlippyMap {
50 - # The callback function for converting the input text to HTML output
51 - static function parse( $input, $argv ) {
52 - global $SlippyMapMarkerList, $SlippyMapCounter;
 47+ var $mapId;
 48+ var $lat;
 49+ var $lon;
 50+ var $width;
 51+ var $height;
 52+ var $mode;
 53+ var $layer;
 54+ var $zoom;
 55+ var $caption;
 56+ var $scale;
 57+ var $resolution;
 58+ var $resolutions;
 59+ var $scales;
 60+
 61+ /**
 62+ * minimum_longitude, minimum_latitude, maximum_longitude, maximum_latitude
 63+ */
 64+ var $bounds;
 65+
 66+ /*
 67+ * Constants
 68+ * Using static members instead of constants because arrays can't be const
 69+ */
 70+ protected static $DEFAULT_IMAGE_FORMAT = "png";
 71+
 72+ /**
 73+ * Supported map modes and their layer types
 74+ */
 75+ public static $MAP_MODES = array(
 76+ "mapnik", "osmarender", "maplint", "cycle"
 77+ );
 78+
 79+ protected static $MAP_OPTIONS = array (
 80+// 'staticRenderService' => 'http://tile.openstreetmap.org/cgi-bin/export?bbox=##bbox##&scale=##scale##&format=##format##',
 81+ 'staticRenderService' => null,
 82+ 'defaultZoomLevel' => 14,
 83+
 84+ /* from OpenLayers XYZ.js */
 85+ 'defaultLayer' => 'mapnik',
 86+ 'numZoomLevels' => 19,
 87+ 'maxResolution' => 156543.0339,
 88+ 'unit' => 'm',
 89+ 'sphericalMercator' => true
 90+ );
 91+
 92+ /** borrowed from OpenLayers.DOTS_PER_UNIT */
 93+ protected static $INCHES_PER_UNIT = array (
 94+ 'dd' => 4374754,
 95+ 'm' => 39.3701
 96+ );
 97+
 98+ /** borrowed from OpenLayers.DOTS_PER_INCH */
 99+ protected static $DOTS_PER_INCH = 72;
 100+
 101+ /** pixel size in meters */
 102+ protected static $PIXEL_SIZE = 0.00028;
 103+
 104+ public function __construct( $mapParams ) {
 105+ global $wgOut, $wgUser, $wgThumbLimits;
53106 wfLoadExtensionMessages( 'SlippyMap' );
54107
55 - // Support old style parameters from $input
56 - // Parse the pipe separated name value pairs (e.g. 'aaa=bbb|ccc=ddd')
57 - // With the new syntax we expect nothing in the $input, so this will result in '' values
58 - $oldStyleParamStrings = explode( '|', $input );
59 - foreach ( $oldStyleParamStrings as $oldStyleParamString ) {
60 - $oldStyleParamString = trim( $oldStyleParamString );
61 - $eqPos = strpos( $oldStyleParamString, "=" );
62 - if ( $eqPos === false ) {
63 - $oldStyleParams[$oldStyleParamString] = "true";
64 - } else {
65 - $oldStyleParams[substr( $oldStyleParamString, 0, $eqPos )] = trim( htmlspecialchars( substr( $oldStyleParamString, $eqPos + 1 ) ) );
66 - }
67 - }
 108+ $this->errors = $this->validate();
 109+ if ( ! $this->errors )
 110+ return false;
 111+
 112+ self::initMap( $mapParams );
 113+ self::setSize();
 114+ self::setZoom();
 115+ self::initResolutionsAndScales();
 116+ self::setBounds();
 117+ }
68118
69 - // Receive new style args: <slippymap aaa=bbb ccc=ddd></slippymap>
70 - if ( isset( $argv['lat'] ) ) {
71 - $lat = $argv['lat'];
72 - } else if ( isset( $oldStyleParams['lat'] ) ) {
73 - $lat = $oldStyleParams['lat'];
74 - } else {
75 - $lat = '';
76 - }
77 - if ( isset( $argv['lon'] ) ) {
78 - $lon = $argv['lon'];
79 - } else if ( isset( $oldStyleParams['lon'] ) ) {
80 - $lon = $oldStyleParams['lon'];
81 - } else {
82 - $lon = '';
83 - }
84 - if ( isset( $argv['z'] ) ) {
85 - $zoom = $argv['z'];
86 - } else if ( isset( $oldStyleParams['z'] ) ) {
87 - $zoom = $oldStyleParams['z'];
88 - } else {
89 - $zoom = '';
90 - }
91 - if ( isset( $argv['w'] ) ) {
92 - $width = $argv['w'];
93 - } else if ( isset( $oldStyleParams['w'] ) ) {
94 - $width = $oldStyleParams['w'];
95 - } else {
96 - $width = '';
97 - }
98 - if ( isset( $argv['h'] ) ) {
99 - $height = $argv['h'];
100 - } else if ( isset( $oldStyleParams['h'] ) ) {
101 - $height = $oldStyleParams['h'];
102 - } else {
103 - $height = '';
104 - }
105 - if ( isset( $argv['layer'] ) ) {
106 - $layer = $argv['layer'];
107 - } else if ( isset( $oldStyleParams['layer'] ) ) {
108 - $layer = $oldStyleParams['layer'];
109 - } else {
110 - $layer = '';
111 - }
112 - if ( isset( $argv['marker'] ) ) {
113 - $marker = $argv['marker'];
114 - } else {
115 - $marker = '';
116 - }
 119+ public function initMap( $mapParams ) {
 120+ $this->mapId = $mapParams['mapId'];
 121+ $this->lat = $mapParams['lat'];
 122+ $this->lon = $mapParams['lon'];
 123+ $this->width = $mapParams['w'];
 124+ $this->height = $mapParams['h'];
 125+ $this->mode = $mapParams['mode'];
 126+ $this->zoom = $mapParams['zoom'];
 127+ $this->caption = $mapParams['caption'];
 128+ $this->layer = isset( $mapParams['layer'] ) ? strtolower($mapParams['layer']) : SlippyMap::$MAP_OPTIONS['defaultLayer'];
 129+ $this->marker = ($mapParams['marker'] != '' && $mapParams['marker'] != '0' ? 1 : 0);
117130
118 - $error = '';
 131+ // see if the 'z' paramater is used rather than 'zoom' (and allow it)
 132+ if ( $this->zoom == '' && isset( $mapParams['z'] ) ) {
 133+ $this->zoom = $mapParams['z'];
 134+ }
 135+ }
 136+
 137+ public function getMap() {
 138+ global $wgOut, $wgJsMimeType;
119139
120 - // default values (meaning these parameters can be missed out)
121 - if ( $width == '' ) $width = '450';
122 - if ( $height == '' ) $height = '320';
123 - if ( $layer == '' ) $layer = 'mapnik';
 140+ $mapCode .= <<<EOT
 141+ <script type="{$wgJsMimeType}">slippymaps.push(new slippymap_map({$this->mapId}, {
 142+ mode: '{$this->mode}',
 143+ layer: '{$this->layer}',
 144+ lat: {$this->lat},
 145+ lon: {$this->lon},
 146+ zoom: {$this->zoom},
 147+ width: {$this->width},
 148+ height: {$this->height},
 149+ marker: {$this->marker}
 150+ }));</script>
 151+EOT;
124152
125 - if ( $zoom == '' && isset( $argv['zoom'] ) ) {
126 - $zoom = $argv['zoom']; // see if they used 'zoom' rather than 'z' (and allow it)
 153+ // TODO: NOSCRIPT support
 154+ if ( isset( SlippyMap::$MAP_OPTIONS['staticRenderService'] ) ) {
 155+ $mapCode .= self::getStaticMap();
 156+ } else {
 157+ $mapCode .= self::getDynamicMap();
127158 }
 159+ return $mapCode;
 160+ }
128161
129 - $marker = ( $marker != '' && $marker != '0' );
 162+ public function getDynamicMap() {
 163+ $mapCode .= <<<EOT
 164+ <div class="mapframe" style="width:{$this->width}px">
 165+ <div id="map{$this->mapId}" class="map" style="width:{$this->width}px; height:{$this->height}px;">
 166+ <script type="{$wgJsMimeType}">slippymaps[{$this->mapId}].init();</script>
 167+ </div>
 168+EOT;
 169+ if ( $this->caption ) {
 170+ $mapcode .= <<<EOT
 171+ <div class="mapcaption">{$this->caption}</div>
 172+EOT;
 173+ }
130174
131 - // trim off the 'px' on the end of pixel measurement numbers (ignore if present)
132 - if ( substr( $width, -2 ) == 'px' )
133 - $width = (int) substr( $width, 0, -2 );
 175+ $mapCode .= <<<EOT
 176+ </div>
 177+EOT;
 178+ return $mapCode;
 179+ }
134180
135 - if ( substr( $height, - 2 ) == 'px' )
136 - $height = (int) substr( $height, 0, -2 );
 181+ public function getStaticMap() {
 182+ $clickToActivate = wfMsg('slippymap_clicktoactivate');
 183+ $staticmap = <<<EOT
 184+ <div class="mapframe" style="width:{$this->width}px;">
 185+ <div id="map{$this->mapId}" class="map" style="width:{$this->width}px; height:{$this->height}px;">
 186+ <!-- Static preview -->
 187+ <img
 188+ id="mapPreview{$this->mapId}"
 189+ class="mapPreview"
 190+ src="{$this->getImgSrc()}"
 191+ onclick="slippymaps[{$this->mapId}].init();"
 192+ width="{$this->width}"
 193+ height="{$this->height}"
 194+ alt="Slippy Map"
 195+ title="{$clickToActivate}"/>
 196+ </div>
 197+EOT;
137198
138 - if ( trim( $input ) != '' && sizeof( $oldStyleParamStrings ) < 3 ) {
139 - $error = 'slippymap tag contents. Were you trying to input KML? KML support ' .
140 - 'is disabled pending discussions about wiki syntax';
141 - $showkml = false;
142 -// KML code:
143 -// if ( $showkml ) {
144 -// $input = str_replace( array( '%', "\n" , "'" , '"' , '<' , '>' , ' ' ),
145 -// array( '%25', '%0A', '%27', '%22', '%3C', '%3E', '%20' ), $input );
146 -// $output .= 'var vector = new OpenLayers.Layer.Vector("Vector Layer"); ' .
147 -// ' map.addLayer(vector); ' .
148 -// ' kml = new OpenLayers.Format.KML( { "internalProjection": map.baseLayer.projection, ' .
149 -// ' "externalProjection": epsg4326, ' .
150 -// ' "extractStyles": true, ' .
151 -// ' "extractAttributes": true } ); ' .
152 -// " features = kml.read(unescape('$input')); " .
153 -// ' vector.addFeatures( features ); ';
154 -// }
155 - } else {
156 - $showkml = false;
157 - }
 199+ if ( $this->caption ) {
 200+ $staticmap .= '<div class="mapcaption">{$this->caption}</div>';
 201+ $staticmap .= '</div>';
 202+ }
158203
159 - // Check required parameters values are provided
160 - if ( $lat == '' ) $error .= wfMsg( 'slippymap_latmissing' ) . ' ';
161 - if ( $lon == '' ) $error .= wfMsg( 'slippymap_lonmissing' ) . ' ';
162 - if ( $zoom == '' ) $error .= wfMsg( 'slippymap_zoommissing' ) . ' ';
 204+ return $staticmap;
 205+ }
163206
164 - if ( $error == '' ) {
165 - // no errors so far. Now check the values
166 - if ( !is_numeric( $width ) ) {
167 - $error = wfMsg( 'slippymap_widthnan', $width );
168 - } else if ( !is_numeric( $height ) ) {
169 - $error = wfMsg( 'slippymap_heightnan', $height );
170 - } else if ( !is_numeric( $zoom ) ) {
171 - $error = wfMsg( 'slippymap_zoomnan', $zoom );
172 - } else if ( !is_numeric( $lat ) ) {
173 - $error = wfMsg( 'slippymap_latnan', $lat );
174 - } else if ( !is_numeric( $lon ) ) {
175 - $error = wfMsg( 'slippymap_lonnan', $lon );
176 - } else if ( $width > 1000 ) {
177 - $error = wfMsg( 'slippymap_widthbig' );
178 - } else if ( $width < 100 ) {
179 - $error = wfMsg( 'slippymap_widthsmall' );
180 - } else if ( $height > 1000 ) {
181 - $error = wfMsg( 'slippymap_heightbig' );
182 - } else if ( $height < 100 ) {
183 - $error = wfMsg( 'slippymap_heightsmall' );
184 - } else if ( $lat > 90 ) {
185 - $error = wfMsg( 'slippymap_latbig' );
186 - } else if ( $lat < -90 ) {
187 - $error = wfMsg( 'slippymap_latsmall' );
188 - } else if ( $lon > 180 ) {
189 - $error = wfMsg( 'slippymap_lonbig' );
190 - } else if ( $lon < -180 ) {
191 - $error = wfMsg( 'slippymap_lonsmall' );
192 - } else if ( $zoom < 0 ) {
193 - $error = wfMsg( 'slippymap_zoomsmall' );
194 - } else if ( $zoom == 18 ) {
195 - $error = wfMsg( 'slippymap_zoom18' );
196 - } else if ( $zoom > 17 ) {
197 - $error = wfMsg( 'slippymap_zoombig' );
198 - }
199 - }
 207+ public function setZoom( $zoom = null ) {
 208+ global $wgOut;
 209+ if ( $this->zoom == '' ) $this->zoom = SlippyMap::$MAP_OPTIONS['defaultZoomLevel'];
 210+ }
 211+
 212+ public function setSize( $w = null, $h = null ) {
 213+ global $wgUser, $wgOut, $wgThumbLimits;
 214+ // set thumbsize based on user preferences
 215+ $thumbsize = $wgThumbLimits[$wgUser->getOption( 'thumbsize' )];
200216
201 - // Find the tile server URL to use. Note that we could allow the user to override that with
202 - // *any* tile server URL for more flexibility, but that might be a security concern.
 217+ // default values (meaning these parameters can be missed out)
 218+ if ( $this->width == '' ) $this->width = $thumbsize;
 219+ if ( $this->height == '' ) $this->height = round( $thumbsize * .72 );
203220
204 - $layer = strtolower( $layer );
205 - $layerObjectDef = '';
206 - if ( $layer == 'osmarender' ) {
207 - $layerObjectDef = 'OpenLayers.Layer.OSM.Osmarender("Osmarender");';
208 - } elseif ( $layer == 'mapnik' ) {
209 - $layerObjectDef = 'OpenLayers.Layer.OSM.Mapnik("Mapnik");';
210 - } elseif ( $layer == 'maplint' ) {
211 - $layerObjectDef = 'OpenLayers.Layer.OSM.Maplint("Maplint");';
212 - } else {
213 - $error = wfMsg( 'slippymap_invalidlayer', htmlspecialchars( $layer ) );
214 - }
 221+ // trim off the 'px' on the end of pixel measurement numbers (ignore if present)
 222+ if ( substr( $this->width, -2 ) == 'px' )
 223+ $this->width = (int) substr( $this->width, 0, -2 );
215224
216 - if ( $error != "" ) {
217 - // Something was wrong. Spew the error message and input text.
218 - $output = '';
219 - $output .= "<span class=\"error\">" . wfMsg( 'slippymap_maperror' ) . ' ' . $error . "</span><br />";
220 - $output .= htmlspecialchars( $input );
221 - return $output;
222 - } else {
223 - $output = self::makeSlippyMapHTMLandJS($lon, $lat, $zoom, $height, $width, $layerObjectDef, $marker, $SlippyMapCounter++);
 225+ if ( substr( $this->height, - 2 ) == 'px' )
 226+ $this->height = (int) substr( $this->height, 0, -2 );
224227
225 - $markercount = count($SlippyMapMarkerList);
226 - $pMarker = "SlippyMap-marker".$markercount."-SlippyMap";
227 - $SlippyMapMarkerList[$markercount] = $output;
228 - return $pMarker;
229 - }
230228 }
231229
232 - static function makeSlippyMapHTMLandJS($lon, $lat, $zoom, $height, $width, $layerObjectDef, $marker, $unique) {
233 - global $wgScriptPath, $wgMapOfServiceUrl;
234 - // HTML output for the slippy map.
235 - // Note that this must all be output on one line (no linefeeds)
236 - // otherwise MediaWiki adds <BR> tags, which is bad in the middle of a block of javascript.
237 - // There are other ways of fixing this, but not for MediaWiki v4
238 - // (See http://www.mediawiki.org/wiki/Manual:Tag_extensions#How_can_I_avoid_modification_of_my_extension.27s_HTML_output.3F)
 230+ public function setBounds() {
239231
240 - $slippymap_code_marker = '';
241 - if ( $marker ) {
242 - $slippymap_code_marker = <<<EOT
243 -var markers${unique} = new OpenLayers.Layer.Markers( "Markers" );
244 -map${unique}.addLayer(markers${unique});
245 -var size${unique} = new OpenLayers.Size(20,34);
246 -var offset${unique} = new OpenLayers.Pixel(-(size${unique}.w/2), -size${unique}.h);
247 -var icon${unique} = new OpenLayers.Icon('http://boston.openguides.org/markers/YELLOW.png', size${unique},offset${unique});
248 -markers${unique}.addMarker(new OpenLayers.Marker( lonLat${unique}, icon${unique} ));
249 -EOT;
250 - }
 232+ /* Determine scale and map bounds for static render request */
 233+ $this->resolution = $this->resolutions[round( $this->zoom )];
 234+ $this->scale = self::getScaleFromResolution( $this->resolution );
251235
252 - $slippymap_code_escaped = Xml::escapeJsString( wfMsg( 'slippymap_code' ) );
253 - $slippymap_button_code = Xml::escapeJsString( wfMsg( 'slippymap_button_code' ) );
254 - $slippymap_resetview = Xml::escapeJsString( wfMsg( 'slippymap_resetview' ) );
 236+ /*
 237+ * Calculate width for Mapnik output using a standard pixel size of 0.00028m
 238+ * @see http://trac.mapnik.org/wiki/ScaleAndPpi
 239+ */
 240+ $w_deg = $this->width * SlippyMap::$PIXEL_SIZE * $this->scale;
 241+ $h_deg = $this->height * SlippyMap::$PIXEL_SIZE * $this->scale;
255242
256 - $slippymap_zoom_snippet = '';
257 - if ( $height > 320 ) {
258 - // Add the zoom bar control, except if the map is only little
259 - $slippymap_zoom_snippet = 'new OpenLayers.Control.PanZoomBar(),';
260 - } else if ( $height > 140 ) {
261 - $slippymap_zoom_snippet = 'new OpenLayers.Control.PanZoom(),';
 243+ $center = array( $this->lon, $this->lat );
 244+ if ( SlippyMap::$MAP_OPTIONS['sphericalMercator'] ) {
 245+ // Calculate bounds within a spherical mercator projection if that is what the scale is based on
 246+ $mercatorCenter = SlippyMap::forwardMercator( $center );
 247+ $mbounds = array(
 248+ $mercatorCenter[0] - $w_deg / 2,
 249+ $mercatorCenter[1] - $h_deg / 2,
 250+ $mercatorCenter[0] + $w_deg / 2,
 251+ $mercatorCenter[1] + $h_deg / 2
 252+ );
 253+ $this->bounds = SlippyMap::inverseMercator( $mbounds );
 254+ }
 255+ else {
 256+ // Calculate bounds within WGS84
 257+ $this->bounds = array( $center[0] - $w_deg / 2, $center[1] - $h_deg / 2, $center[0] + $w_deg / 2, $center[1] + $h_deg / 2 );
 258+ }
 259+ }
 260+
 261+ public function getImgSrc() {
 262+ if ( $this->isValidMode() && isset( SlippyMap::$MAP_OPTIONS['staticRenderService'] ) ) {
 263+ return $this->parameterize( SlippyMap::$MAP_OPTIONS['staticRenderService'],
 264+ array( 'bbox' => implode( ',', $this->bounds ),
 265+ 'scale' => $this->scale,
 266+ 'lat' => $this->lat,
 267+ 'long' => $this->lon,
 268+ 'z' => $this->zoom,
 269+ 'w' => $this->width,
 270+ 'h' => $this->height,
 271+ 'format' => SlippyMap::$DEFAULT_IMAGE_FORMAT
 272+ )
 273+ );
262274 }
 275+ }
 276+
 277+ /**
 278+ * Substitutes parameters in a template using double hash sign delimiters, for example:
 279+ *
 280+ * <code>
 281+ * <tag xml:lang="##lang##"/>
 282+ * </code>
 283+ *
 284+ * A corresponding parameter "lang" may then be used to provide a replacement that is
 285+ * transparently substituted.
 286+ *
 287+ * @param string $template The template text
 288+ * @param array $params A map with parameter names as keys and their replacements as values
 289+ * @return string Parameterized text
 290+ */
 291+ protected static function parameterize( $template, $params ) {
 292+ foreach ( $params as $key => $value ) {
 293+ $template = str_replace( "##{$key}##", $value, $template );
 294+ }
 295+ return $template;
 296+ }
 297+
 298+ /**
 299+ * Borrowed from OpenLayers.Util.getScaleFromResolution
 300+ */
 301+ protected function getScaleFromResolution( $resolution ) {
 302+ return $resolution * SlippyMap::$INCHES_PER_UNIT[SlippyMap::$MAP_OPTIONS['unit']] * SlippyMap::$DOTS_PER_INCH;
 303+ }
 304+
 305+ /**
 306+ * Determines resolutions and scales based on a maximum resolution and number of zoom levels
 307+ * Borrowed from OpenLayers.Layer.initResolutions
 308+ */
 309+ protected function initResolutionsAndScales() {
 310+ $this->resolutions = array();
 311+ $base = 2;
 312+
 313+ for ( $i = 0; $i < SlippyMap::$MAP_OPTIONS['numZoomLevels']; $i++ ) {
 314+ $this->resolutions[$i] = SlippyMap::$MAP_OPTIONS['maxResolution'] / pow( $base, $i );
 315+ $this->scales[$i] = $this->getScaleFromResolution( $this->resolutions[$i] );
 316+ }
 317+ }
 318+
 319+ /**
 320+ * Convert from WGS84 to spherical mercator
 321+ */
 322+ protected static function forwardMercator($lonlat) {
 323+ for ($i=0; $i<count($lonlat); $i+=2) {
 324+ /* lon */
 325+ $lonlat[$i] = $lonlat[$i] * (2 * M_PI * 6378137 / 2.0) / 180.0;
 326+
 327+ /* lat */
 328+ $lonlat[$i+1] = log(tan((90 + $lonlat[$i+1]) * M_PI / 360.0)) / (M_PI / 180.0);
 329+ $lonlat[$i+1] = $lonlat[$i+1] * (2 * M_PI * 6378137 / 2.0) / 180.0;
 330+ }
 331+ return $lonlat;
 332+ }
 333+
 334+ /**
 335+ * Convert from spherical mercator to WGS84
 336+ */
 337+ protected static function inverseMercator($lonlat) {
 338+ for ($i=0; $i<count($lonlat); $i+=2) {
 339+ /* lon */
 340+ $lonlat[$i] = $lonlat[$i] / ((2 * M_PI * 6378137 / 2.0) / 180.0);
 341+
 342+ /* lat */
 343+ $lonlat[$i+1] = $lonlat[$i+1] / ((2 * M_PI * 6378137 / 2.0) / 180.0);
 344+ $lonlat[$i+1] = 180.0 / M_PI * (2 * atan(exp($lonlat[$i+1] * M_PI / 180.0)) - M_PI / 2);
 345+ }
 346+
 347+ return $lonlat;
 348+ }
263349
264 - $output = <<<EOT
265 -<!-- Slippy Map -->
 350+ public function validMode( $mode ) {
 351+ global $wgMapModes;
 352+ $this->errors = '';
 353+
 354+ if ( ! in_array( $mode, $wgMapModes ) ) {
 355+ $this->errors .= wfMsg( 'slippymap_invalidmode', htmlspecialchars( $this->mode ) );
 356+ return false;
 357+ }
266358
267 -<!-- This inline stylesheet defines how the two extra buttons look, and where they are positioned. -->
268 -<style> .buttonsPanel div { float:left; display:block; position:relative; left:50px; margin-left:3px; margin-top:7px; width:36px; height:19px; }</style>
269 -<style> .buttonsPanel .getWikiCodeButtonItemInactive { width:36px; height:19px; background-image:url('$wgScriptPath/extensions/SlippyMap/wikicode-button.png'); }</style>
270 -<style> .buttonsPanel .resetButtonItemInactive { width:36px; height:19px; background-image:url('$wgScriptPath/extensions/SlippyMap/reset-button.png'); }</style>
 359+ return true;
 360+ }
 361+
 362+ public function validate() {
 363+ wfLoadExtensionMessages( 'SlippyMap' );
 364+ $errors = null;
 365+
 366+ if ( $this->lat == '' ) $errors .= wfMsg( 'slippymap_latmissing' ) . ' ';
 367+ if ( $this->lon == '' ) $errors .= wfMsg( 'slippymap_lonmissing' ) . ' ';
 368+ if ( $this->zoom == '' ) $errors .= wfMsg( 'slippymap_zoommissing' ) . ' ';
271369
272 -<!-- bring in the OpenLayers javascript library -->
273 -<script src="http://openlayers.org/api/OpenLayers.js"></script>
 370+ if ( $errors == '' ) {
 371+ // no errors so far. Now check the values
 372+ if ( !is_numeric( $this->width ) ) {
 373+ $errors = wfMsg( 'slippymap_widthnan', $this->width );
 374+ } else if ( !is_numeric( $this->height ) ) {
 375+ $errors = wfMsg( 'slippymap_heightnan', $this->height );
 376+ } else if ( !is_numeric( $this->zoom ) ) {
 377+ $errors = wfMsg( 'slippymap_zoomnan', $this->zoom );
 378+ } else if ( !is_numeric( $this->lat ) ) {
 379+ $errors = wfMsg( 'slippymap_latnan', $this->lat );
 380+ } else if ( !is_numeric( $this->lon ) ) {
 381+ $errors = wfMsg( 'slippymap_lonnan', $this->lon );
 382+ } else if ( $this->width > 1000 ) {
 383+ $errors = wfMsg( 'slippymap_widthbig' );
 384+ } else if ( $this->width < 100 ) {
 385+ $errors = wfMsg( 'slippymap_widthsmall' );
 386+ } else if ( $this->height > 1000 ) {
 387+ $errors = wfMsg( 'slippymap_heightbig' );
 388+ } else if ( $this->height < 100 ) {
 389+ $errors = wfMsg( 'slippymap_heightsmall' );
 390+ } else if ( $this->lat > 90 ) {
 391+ $errors = wfMsg( 'slippymap_latbig' );
 392+ } else if ( $this->lat < -90 ) {
 393+ $errors = wfMsg( 'slippymap_latsmall' );
 394+ } else if ( $this->lon > 180 ) {
 395+ $errors = wfMsg( 'slippymap_lonbig' );
 396+ } else if ( $this->lon < -180 ) {
 397+ $errors = wfMsg( 'slippymap_lonsmall' );
 398+ } else if ( $this->zoom < 0 ) {
 399+ $errors = wfMsg( 'slippymap_zoomsmall' );
 400+ } else if ( $this->zoom == 18 ) {
 401+ $errors = wfMsg( 'slippymap_zoom18' );
 402+ } else if ( $this->zoom > 17 ) {
 403+ $errors = wfMsg( 'slippymap_zoombig' );
 404+ }
 405+ }
 406+
 407+ return $errors;
 408+ }
 409+
 410+ public function getErrors() {
 411+ if ( $this->errors != "" ) {
 412+ // Something was wrong. Spew the error message and input text.
 413+ $output = '';
 414+ $output .= "<span class=\"error\">" . wfMsg( 'slippymap_maperror' ) . ' ' . $this->errors . "</span><br />";
 415+ $output .= htmlspecialchars( $input );
 416+ return $output;
 417+ }
 418+ }
274419
275 -<!-- bring in the OpenStreetMap OpenLayers layers.
276 - Using this hosted file will make sure we are kept up
277 - to date with any necessary changes -->
278 -<script src="http://openstreetmap.org/openlayers/OpenStreetMap.js"></script>
 420+ public function getMapId() {
 421+ return $this->mapId;
 422+ }
279423
280 -<script type="text/javascript">
281 - var lon${unique} = ${lon};
282 - var lat${unique} = ${lat};
283 - var zoom${unique} = ${zoom};
 424+ public function getLat() {
 425+ return $this->lat;
 426+ }
284427
285 - var lonLat${unique};
286 - var map${unique};
 428+ public function getLon() {
 429+ return $this->lon;
 430+ }
287431
288 - addOnloadHook( slippymap_init );
289 -
290 - function slippymap_resetPosition${unique}() {
291 - map${unique}.setCenter(lonLat${unique}, zoom${unique});
 432+ public function getWidth() {
 433+ return $this->width;
292434 }
293435
294 - function slippymap_getWikicode${unique}() {
295 - LL = map${unique}.getCenter().transform(map${unique}.getProjectionObject(), new OpenLayers.Projection("EPSG:4326"));
296 - Z = map${unique}.getZoom();
297 - size = map${unique}.getSize();
298 - prompt(
299 - "${slippymap_code_escaped}",
300 - "<slippymap h=" + size.h + " w=" + size.w + " z=" + Z + " lat=" + LL.lat + " lon=" + LL.lon + " layer=mapnik marker=1 />"
301 - );
 436+ public function getHeight() {
 437+ return $this->height;
302438 }
303439
304 - function slippymap_init() {
305 - // FIXME: Replace with OpenLayers.Layer.OSM?: http://trac.openlayers.org/changeset/9240
306 - map${unique} = new OpenLayers.Map("map${unique}", {
307 - controls:[
308 - new OpenLayers.Control.Navigation(),
309 - $slippymap_zoom_snippet
310 - new OpenLayers.Control.Attribution()
311 - ],
312 - maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
313 - maxResolution:156543.0399,
314 - units: 'meters',
315 - projection: "EPSG:900913"
316 - });
317 -
318 - layer = new ${layerObjectDef};
319 - map${unique}.addLayer(layer);
320 - epsg4326 = new OpenLayers.Projection("EPSG:4326");
321 - lonLat${unique} = new OpenLayers.LonLat(lon${unique}, lat${unique}).transform( epsg4326, map${unique}.getProjectionObject() );
322 -
323 - $slippymap_code_marker
324 -
325 - map${unique}.setCenter(lonLat${unique}, zoom${unique});
326 -
327 - var getWikiCodeButton${unique} = new OpenLayers.Control.Button({
328 - title: "${slippymap_button_code}",
329 - displayClass: "getWikiCodeButton",
330 - trigger: slippymap_getWikicode${unique}
331 - });
332 -
333 - var resetButton${unique} = new OpenLayers.Control.Button({
334 - title: "${slippymap_resetview}",
335 - displayClass: "resetButton",
336 - trigger: slippymap_resetPosition${unique}
337 - });
338 -
339 - var panel${unique} = new OpenLayers.Control.Panel( { displayClass: "buttonsPanel" } );
340 - panel${unique}.addControls([getWikiCodeButton${unique}, resetButton${unique}]);
341 - map${unique}.addControl(panel${unique});
 440+ public function getMode() {
 441+ return $this->mode;
342442 }
343 -</script>
344443
345 -<div style="width: {$width}px; height:{$height}px; border-style:solid; border-width:1px; border-color:lightgrey;" id="map${unique}">
346 -<noscript>
347 - <a href="http://www.openstreetmap.org/?lat=${lat}&lon=${lon}&zoom=${zoom}" title="See this map on OpenStreetMap.org" style="text-decoration:none">
348 - <img
349 - src="${wgMapOfServiceUrl}lat=${lat}&long=${lon}&z=${zoom}&w=${width}&h=${height}&format=jpeg"
350 - width="${width}"
351 - height="${height}"
352 - border="0"
353 - alt="Slippy Map" />
354 - <br />
355 - </a>
356 -</noscript>
357 -</div>
358 -EOT;
359 -
360 - return $output;
 444+ public function getZoom() {
 445+ return $this->zoom;
361446 }
362447
363 - // Hack, see beginning of file for why
364 - static function ParserAfterTidy(&$parser, &$text) {
365 - global $SlippyMapMarkerList;
366 - $keys = array();
367 - $marker_count = count($SlippyMapMarkerList);
368 -
369 - for ($i = 0; $i < $marker_count; $i++) {
370 - $keys[] = 'SlippyMap-marker' . $i . '-SlippyMap';
371 - }
372 -
373 - $text = str_replace($keys, $SlippyMapMarkerList, $text);
374 - return true;
 448+ public function getLayer() {
 449+ return $this->layer;
375450 }
376451 }
Index: trunk/extensions/SlippyMap/SlippyMap.js
@@ -0,0 +1,213 @@
 2+/*
 3+ * @file
 4+ *
 5+ * @description
 6+ *
 7+ * OpenStreetMap SlippyMap - MediaWiki extension
 8+ *
 9+ * This defines what happens when <slippymap> tag is placed in the wikitext
 10+ *
 11+ * We show a map based on the lat/lon/zoom data passed in. This extension brings in
 12+ * the OpenLayers javascript, to show a slippy map.
 13+ *
 14+ * Usage example:
 15+ * <slippymap lat=51.485 lon=-0.15 z=11 w=300 h=200 layer=osmarender></slippymap>
 16+ *
 17+ * Tile images are not cached local to the wiki.
 18+ * To acheive this (remove the OSM dependency) you might set up a squid proxy,
 19+ * and modify the requests URLs here accordingly.
 20+ *
 21+ * This file should be placed in the mediawiki 'extensions' directory
 22+ * ...and then it needs to be 'included' within LocalSettings.php
 23+ *
 24+ * @license
 25+ *
 26+ * Copyright 2008 Harry Wood, Jens Frank, Grant Slater, Raymond Spekking and others
 27+ *
 28+ * This program is free software; you can redistribute it and/or modify
 29+ * it under the terms of the GNU General Public License as published by
 30+ * the Free Software Foundation; either version 2 of the License, or
 31+ * (at your option) any later version.
 32+ *
 33+ * This program is distributed in the hope that it will be useful,
 34+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 35+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 36+ * GNU General Public License for more details.
 37+ *
 38+ * You should have received a copy of the GNU General Public License
 39+ * along with this program; if not, write to the Free Software
 40+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 41+ *
 42+ */
 43+
 44+var slippymaps = new Array();
 45+var mapId = 0;
 46+var layer = null;
 47+
 48+if (autoInitMaps) {
 49+ addOnloadHook(slippymap_init);
 50+ addOnloadHook(prepPopupMap);
 51+}
 52+
 53+function slippymap_init() {
 54+ for (i=0; i < slippymaps.length; i++) {
 55+ slippymaps[i].init();
 56+ }
 57+}
 58+
 59+function slippymap_map(mapId, mapParams) {
 60+ var self = this;
 61+ this.mapId = mapId;
 62+
 63+ for (key in mapParams)
 64+ this[key] = mapParams[key];
 65+
 66+ var buttonsPanel = new OpenLayers.Control.Panel( { displayClass: "buttonsPanel" } );
 67+ buttonsPanel.addControls([ new OpenLayers.Control.Button({
 68+ title: wgSlippyMapButtonCode,
 69+ displayClass: "getWikiCodeButton",
 70+ trigger: function() { self.getWikicode(); }
 71+ }),
 72+ new OpenLayers.Control.Button({
 73+ title: wgSlippyMapResetview,
 74+ displayClass: "resetButton",
 75+ trigger: function() { self.resetPosition(); }
 76+ })
 77+ ]);
 78+
 79+ this.mapOptions = { controls: [ new OpenLayers.Control.Navigation(),
 80+ new OpenLayers.Control.ArgParser(),
 81+ new OpenLayers.Control.Attribution(),
 82+ new OpenLayers.Control.LayerSwitcher(),
 83+ buttonsPanel ]
 84+ };
 85+
 86+ /* Add the zoom bar control, except if the map is only little */
 87+ if (this.height > 320)
 88+ this.mapOptions.controls.push(new OpenLayers.Control.PanZoomBar());
 89+ else if (this.height > 140)
 90+ this.mapOptions.controls.push(new OpenLayers.Control.PanZoom());
 91+}
 92+
 93+slippymap_map.prototype.init = function() {
 94+ /* Swap out against the preview image */
 95+ var previewImage = document.getElementById('mapPreview' + this.mapId);
 96+ if (previewImage)
 97+ previewImage.style.display = 'none';
 98+
 99+ switch(this.mode) {
 100+ case "satellite":
 101+ /* Nasa WorldWind */
 102+ this.map = this.ww_create(this.mapId, this.lon, this.lat, this.zoom, this.layer);
 103+ break;
 104+ case "wms":
 105+ /* wms map */
 106+ this.map = this.wms_create(this.mapId, this.lon, this.lat, this.zoom, this.layer);
 107+ break;
 108+ default:
 109+ /* OpenStreetMap */
 110+ this.map = this.osm_create(this.mapId, this.lon, this.lat, this.zoom);
 111+ }
 112+
 113+ if (this.marker) {
 114+ var markers = new OpenLayers.Layer.Markers( "Markers" );
 115+ this.map.addLayer(markers);
 116+ var size = new OpenLayers.Size(20,34);
 117+ var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
 118+ var icon = new OpenLayers.Icon('http://boston.openguides.org/markers/YELLOW.png', size, offset);
 119+ markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(this.lon, this.lat).transform(new OpenLayers.Projection('EPSG:4326'), this.map.getProjectionObject()), icon));
 120+ }
 121+}
 122+
 123+slippymap_map.prototype.osm_create = function(mapId, lon, lat, zoom) {
 124+ var map;
 125+ var osmLayer;
 126+ map = new OpenLayers.Map('map' + mapId, this.mapOptions /* all provided for by OSM.js */);
 127+
 128+ if (this.layer == 'mapnik' ) {
 129+ osmLayer = new OpenLayers.Layer.OSM();
 130+ } else if (this.layer == 'osmarender' ) {
 131+ osmLayer = new OpenLayers.Layer.OSM("t@h",
 132+ [ "http://a.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png",
 133+ "http://b.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png",
 134+ "http://c.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png"]);
 135+ } else if (this.layer == 'maplint' ) {
 136+ osmLayer = new OpenLayers.Layer.OSM("maplint",
 137+ [ "http://a.tah.openstreetmap.org/Tiles/maplint/${z}/${x}/${y}.png",
 138+ "http://b.tah.openstreetmap.org/Tiles/maplint/${z}/${x}/${y}.png",
 139+ "http://c.tah.openstreetmap.org/Tiles/maplint/${z}/${x}/${y}.png"]);
 140+ } else if (this.layer == 'cycle' ) {
 141+ osmLayer = new OpenLayers.Layer.OSM("cycle",
 142+ [ "http://a.thunderflames.org/tiles/cycle/${z}/${x}/${y}.png",
 143+ "http://b.thunderflames.org/tiles/cycle/${z}/${x}/${y}.png",
 144+ "http://c.thunderflames.org/tiles/cycle/${z}/${x}/${y}.png"]);
 145+ }
 146+
 147+ map.addLayers([osmLayer]);
 148+ map.setCenter(new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection('EPSG:4326'), map.getProjectionObject()), zoom);
 149+ return map;
 150+}
 151+
 152+/* Nasa WorldWind
 153+ * TODO make configurable
 154+ */
 155+slippymap_map.prototype.ww_create = function(mapId, lon, lat, zoom, layer) {
 156+ var map;
 157+ var wwLayer;
 158+ this.mapOptions.maxResolution = 1.6;
 159+ this.mapOptions.numZoomLevels = 21;
 160+
 161+ map = new OpenLayers.Map('map' + mapId, this.mapOptions);
 162+
 163+ if (this.layer == 'urban' ) {
 164+ wwLayer = new OpenLayers.Layer.WorldWind( 'urban',
 165+ "http://worldwind25.arc.nasa.gov/tile/tile.aspx?", .8, 9,
 166+ {T:"104"}, { tileSize: new OpenLayers.Size(512,512) });
 167+ // TODO
 168+ } else if (this.layer == 'landsat') {
 169+
 170+ // TODO
 171+ } else if (this.layer == 'bluemarble') {
 172+
 173+ }
 174+
 175+ map.addLayers([wwLayer]);
 176+ map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
 177+ return map;
 178+}
 179+
 180+/* WMS custom map
 181+ * TODO make configurable
 182+ */
 183+slippymap_map.prototype.wms_create = function(mapId, lon, lat, zoom) {
 184+ /* ? */
 185+ var map;
 186+ this.mapOptions.maxResolution = 360/512/16;
 187+ this.mapOptions.numZoomLevels = 15;
 188+ map = new OpenLayers.Map('map' + mapId, this.mapOptions);
 189+ wmsLayer = new OpenLayers.Layer.WMS(
 190+ "Fire detects", "http://map.ngdc.noaa.gov/wmsconnector/com.esri.wms.Esrimap/firedetects",
 191+ {
 192+ layers: 'firedetects',
 193+ format: 'image/png'
 194+ });
 195+ map.addLayers([wmsLayer]);
 196+ map.setCenter(new OpenLayers.LonLat( lon, lat ), zoom);
 197+ return map;
 198+}
 199+
 200+slippymap_map.prototype.resetPosition = function() {
 201+ this.map.setCenter(new OpenLayers.LonLat(this.lon, this.lat).transform(new OpenLayers.Projection('EPSG:4326'), this.map.getProjectionObject()), this.zoom);
 202+}
 203+
 204+slippymap_map.prototype.getWikicode = function() {
 205+ LL = this.map.getCenter().transform(this.map.getProjectionObject(), new OpenLayers.Projection("EPSG:4326"));
 206+ Z = this.map.getZoom();
 207+ size = this.map.getSize();
 208+
 209+ prompt(
 210+ wgSlippyMapCode,
 211+ "<slippymap h=" + size.h + " w=" + size.w + " z=" + Z + " lat=" + LL.lat + " lon=" + LL.lon + " mode=" + this.mode + " layer=" + this.layer + " marker=" + this.marker + " />"
 212+ );
 213+}
 214+
Property changes on: trunk/extensions/SlippyMap/SlippyMap.js
___________________________________________________________________
Name: svn:eol-style
1215 + native
Name: svn:executable
2216 + *
Index: trunk/extensions/SlippyMap/SlippyMap.alias.php
@@ -0,0 +1,16 @@
 2+<?php
 3+/**
 4+ * Aliases for special pages
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+$aliases = array();
 11+
 12+/** English */
 13+$aliases['en'] = array(
 14+ 'SlippyMap' => array( 'SlippyMap' )
 15+);
 16+
 17+
Property changes on: trunk/extensions/SlippyMap/SlippyMap.alias.php
___________________________________________________________________
Name: svn:eol-style
118 + native
Name: svn:executable
219 + *
Index: trunk/extensions/SlippyMap/SlippyMap.worldwind.php
@@ -0,0 +1,142 @@
 2+<?php
 3+/**
 4+*
 5+* @file
 6+*
 7+* @description
 8+* OpenStreetMap SlippyMap - MediaWiki extension
 9+*
 10+* This defines what happens when <slippymap> tag is placed in the wikitext
 11+*
 12+* We show a map based on the lat/lon/zoom data passed in. This extension brings in
 13+* the OpenLayers javascript, to show a slippy map.
 14+*
 15+* Usage example:
 16+* <slippymap lat="51.485" lon="-0.15" z="11" w="300" h="200" layer="osmarender" marker="0" />
 17+*
 18+* Tile images are not cached local to the wiki.
 19+* To acheive this (remove the OSM dependency) you might set up a squid proxy,
 20+* and modify the requests URLs here accordingly.
 21+*
 22+* This file should be placed in the mediawiki 'extensions' directory
 23+* ...and then it needs to be 'included' within LocalSettings.php
 24+*
 25+* @license
 26+*
 27+* Copyright 2008 Harry Wood, Jens Frank, Grant Slater, Raymond Spekking and others
 28+*
 29+* This program is free software; you can redistribute it and/or modify
 30+* it under the terms of the GNU General Public License as published by
 31+* the Free Software Foundation; either version 2 of the License, or
 32+* (at your option) any later version.
 33+*
 34+* This program is distributed in the hope that it will be useful,
 35+* but WITHOUT ANY WARRANTY; without even the implied warranty of
 36+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 37+* GNU General Public License for more details.
 38+*
 39+* You should have received a copy of the GNU General Public License
 40+* along with this program; if not, write to the Free Software
 41+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 42+*
 43+*/
 44+
 45+class WorldWind extends SlippyMap {
 46+
 47+ /**
 48+ * Supported map modes and their layer types
 49+ */
 50+ public static $MAP_MODES = array(
 51+ "urban", "landsat", "bluemarble"
 52+ );
 53+
 54+ protected static $MAP_OPTIONS = array (
 55+ 'staticRenderService' => null,
 56+ 'defaultZoomLevel' => 14,
 57+
 58+ /* from OpenLayers XYZ.js */
 59+ 'defaultLayer' => 'landsat',
 60+ 'numZoomLevels' => 19,
 61+ 'maxResolution' => 156543.0339,
 62+ 'unit' => 'm',
 63+ 'sphericalMercator' => true
 64+ );
 65+
 66+ public function __construct( $mapParams ) {
 67+ global $wgOut, $wgUser, $wgThumbLimits;
 68+ wfLoadExtensionMessages( 'SlippyMap' );
 69+
 70+ $this->errors = $this->validate();
 71+ if ( ! $this->errors )
 72+ return false;
 73+
 74+ self::initMap( $mapParams );
 75+ self::setSize();
 76+ self::setZoom();
 77+ self::initResolutionsAndScales();
 78+ self::setBounds();
 79+ }
 80+
 81+ public function initMap( $mapParams ) {
 82+ $this->mapId = $mapParams['mapId'];
 83+ $this->lat = $mapParams['lat'];
 84+ $this->lon = $mapParams['lon'];
 85+ $this->width = $mapParams['w'];
 86+ $this->height = $mapParams['h'];
 87+ $this->mode = $mapParams['mode'];
 88+ $this->zoom = $mapParams['zoom'];
 89+ $this->caption = $mapParams['caption'];
 90+ $this->layer = isset( $mapParams['layer'] ) ? strtolower($mapParams['layer']) : WorldWind::$MAP_OPTIONS['defaultLayer'];
 91+ $this->marker = ($mapParams['marker'] != '' && $mapParams['marker'] != '0' ? 1 : 0);
 92+
 93+ // see if the 'z' paramater is used rather than 'zoom' (and allow it)
 94+ if ( $this->zoom == '' && isset( $mapParams['z'] ) ) {
 95+ $this->zoom = $mapParams['z'];
 96+ }
 97+ }
 98+
 99+ public function getMap() {
 100+ global $wgOut, $wgJsMimeType;
 101+
 102+ $mapCode .= <<<EOT
 103+ <script type="{$wgJsMimeType}">slippymaps.push(new slippymap_map({$this->mapId}, {
 104+ mode: '{$this->mode}',
 105+ layer: '{$this->layer}',
 106+ lat: {$this->lat},
 107+ lon: {$this->lon},
 108+ zoom: {$this->zoom},
 109+ width: {$this->width},
 110+ height: {$this->height},
 111+ marker: {$this->marker}
 112+ }));</script>
 113+EOT;
 114+
 115+ $mapCode .= self::getDynamicMap();
 116+
 117+ return $mapCode;
 118+ }
 119+
 120+ public function getDynamicMap() {
 121+ $mapCode .= <<<EOT
 122+ <div class="mapframe" style="width:{$this->width}px">
 123+ <div id="map{$this->mapId}" class="map" style="width:{$this->width}px; height:{$this->height}px;">
 124+ <script type="{$wgJsMimeType}">slippymaps[{$this->mapId}].init();</script>
 125+ </div>
 126+EOT;
 127+ if ( $this->caption ) {
 128+ $mapcode .= <<<EOT
 129+ <div class="mapcaption">{$this->caption}</div>
 130+EOT;
 131+ }
 132+
 133+ $mapCode .= <<<EOT
 134+ </div>
 135+EOT;
 136+ return $mapCode;
 137+ }
 138+
 139+ public function setZoom( $zoom = null ) {
 140+ global $wgOut;
 141+ if ( $this->zoom == '' ) $this->zoom = WorldWind::$MAP_OPTIONS['defaultZoomLevel'];
 142+ }
 143+}
Property changes on: trunk/extensions/SlippyMap/SlippyMap.worldwind.php
___________________________________________________________________
Name: svn:eol-style
1144 + native
Name: svn:executable
2145 + *

Follow-up revisions

RevisionCommit summaryAuthorDate
r52348Follow-up r52343: Add alias file to translatewikiraymond06:43, 24 June 2009

Comments

#Comment by Raymond (talk | contribs)   11:31, 27 June 2009

Seen at translatewiki.net, running r52486. (extension disabled for the moment due to the errors)

PHP Notice: Undefined index: mode in /var/www/w/extensions/SlippyMap/SlippyMap.hooks.php on line 127


Status & tagging log