User:Dschwen/Dynamap
From Wikipedia, the free encyclopedia
<?php
- Dynamap WikiMedia extension
- introduces
- * <dynamap></dynamap> Tags
- * Special:DynamapConstants
- Note: The output is not interpreted as WikiText but directly
- included in the HTML output. So Wiki markup is not supported.
- To activate the extension, include it from your LocalSettings.php
- with: include("extensions/ExampleExt.php");
if (!defined('MEDIAWIKI')) die(); $wgExtensionFunctions[] = "wfDynamapExtension";
function wfDynamapExtension() { global $wgParser,$IP, $wgMessageCache;
require_once( "$IP/includes/SpecialPage.php" );
# register the extension with the WikiText parser # the first parameter is the name of the new tag. # In this case it defines the tag <example> ... </example> # the second parameter is the callback function for # processing the text between the tags $wgParser->setHook( "dynamap", "renderDynamap" );
# register the dynamap constant list special page $wgMessageCache->addMessages(array('dynamapconstants' => 'Dynamap Constants'));
class DynamapSpecialPage extends SpecialPage {
function DynamapSpecialPage() { SpecialPage::SpecialPage( 'DynamapConstants' ); #$this->includable( true ); }
function execute( $par = null ) { global $wgOut, $wgRequest; require_once( "maps.inc" );
[edit] Dynamap Extension Constants
[edit] List of available Map Sources
";
foreach ($maplist as $key => $value ) {
$out .= "\n";
}
$out .= "
$key | $value[1] |
[edit] List of predefined Regions
";
//$wgOut->addHTML( $out ); }
}
SpecialPage::addPage( new DynamapSpecialPage ); }
function dynamapError($text) {
return '
'.$text."
";
}
function dynamapFindTemplate($haystack,$needle,&$offset) { $length=strlen($needle); $pos1=strpos(trim($haystack),$needle,$offset); if(!($pos1===false)) { $pos2=strpos($haystack,'}}',$pos1); if(!($pos2===false)) { $offset=$pos2; return trim(substr($haystack,$pos1+$length,$pos2-$pos1-$length)); } } return ; }
function dynamapProject($x,$y,&$px,&$py,$w,$h,$minlat,$minlong,$maxlat,$maxlong) { $px=(($x-$minlong)/($maxlong-$minlong)*$w); $py=$h-(($y-$minlat)/($maxlat-$minlat)*$h); }
function dynamapGetRawText($title,$cur) { $mtitle=Title::newFromURL($title);
$dbr =& wfGetDB( DB_SLAVE ); $t = $dbr->strencode( $mtitle->getDBKey() ); $ns = $mtitle->getNamespace();
if($ns == NS_MEDIAWIKI) return wfMsg($t); else { $sql = "SELECT cur_id as id,cur_timestamp as timestamp,cur_user as user,cur_user_text as user_text," . "cur_restrictions as restrictions,cur_comment as comment,cur_text as text FROM $cur " . "WHERE cur_namespace=$ns AND cur_title='$t'";
$res = $dbr->query( $sql, $fname );
if( $s = $dbr->fetchObject( $res ) ) return Article::getRevisionText( $s, "" );
else return ; } }
function renderDynamap( $input, $argv="" ) { # $argv is an array containing any arguments passed to the extension like <example argument="foo" bar>..
$w=0; $h=0; $maparea=""; $data=false; $css="text {font-family:Verdana; font-size:12px; fill:black;}\n"; $alt_text="Map showing: "; $paths=""; $outfilenamebase="images/dynamap/".md5($input);
$dbr =& wfGetDB( DB_SLAVE ); extract( $dbr->tableNames( 'cur' ) );
$level=1; $color="black"; $radius=3; $stroke=1; $textcolor="black";
$lines = explode("\n", $input); foreach($lines as $line) { if($line[0]!='#') { $command = explode(":", $line); $output.=$command[0]; if(!$data) switch($command[0]) { case "image": $values=explode(",",$command[1]); $w=intval($values[0]); $h=intval($values[1]); break; case "area" : $maparea=$command[1]; list($minlat,$minlong,$maxlat,$maxlong)=explode(",",$command[1]); if($minlat>$maxlat) list($maxlat,$minlat) = array($minlat,$maxlat); if($minlong>$maxlong) list($maxlong,$minlong) = array($minlong,$maxlong); $ah=abs($maxlat-$minlat); $aw=abs($maxlong-$minlong); //return "minlat=$minlat,minlong=$minlong,maxlat=$maxlat,maxlong=$maxlong, ah=$ah,aw=$aw, maparea=$maparea"; break; case "start": if($maparea=="" || $ah==0) return dynamapError("No propper area:latmin,longmin,latmax,longmax command found!"); if($w!=0 && $h==0) { $h=intval(($ah/$aw)*floatval($w)); } if($w==0 || $h==0) return dynamapError("No propper image:w,h or image:w command found!"); $data=true; //return "$w x $h"; break; } else switch($command[0]) { case "level": $level=intval($command[1]); break; case "color": $color=$command[1]; break; case "radius":$radius=floatval($command[1]); break; case "stroke":$stroke=floatval($command[1]); break;
case "layer": $dirtylayer=trim($command[1]); $layer=str_replace(array('"','/','.','%','\\','?','*','!','(',')','{','}'),,$dirtylayer);
# check if raw map exists, otherwise create $map_raw_cache="images/dynamap/".md5($maparea.'_'.$w.'x'.$h.$layer.$level)."raw.svg"; if ( is_readable($map_raw_cache) ) { $paths.=file_get_contents($map_raw_cache); } else { $command="extensions/dynamap/drawmap ".escapeshellcmd($maparea)." $w,$h $level $layer"; //exec("$command 2>&1", $out1, $err); exec("$command", $out1, $err); $out2=implode("\n",$out1);
//file_put_contents($map_raw_cache,$out2); $res=fopen($map_raw_cache,'w'); fwrite($res,$out2); fclose($res);
$paths.=$out2; } $css.=" path.$layer {fill: gray; stroke: $color; stroke-width:$stroke }\n"; break;
case "poly": $text=dynamapGetRawText(trim($command[1]),$cur); $alt_text.=$text.', '; $mtitle=Title::newFromURL(trim($command[1])); $link=$mtitle->getDBKey(); $pos=0; $coords=explode('|',dynamapFindTemplate($text,'{{geopoly',$pos)); $mode=trim(array_shift($coords)); $px=0; $py=0; $first=true; $paths.="<a xlink:href=\"/index.php/$link\">"; while(count($coords)>=4) { $y=trim(array_shift($coords)); if(strtoupper(trim(array_shift($coords)))=='S') $y*=-1; $x=trim(array_shift($coords)); if(strtoupper(trim(array_shift($coords)))=='W') $x*=-1;
dynamapProject($x,$y,$px,$py,$w,$h,$minlat,$minlong,$maxlat,$maxlong); if($first) { $paths.="<path d=\"M $px $py "; $first=false; } else $paths.="L $px $py "; } if(!$first) $paths.="\" style=\"stroke:$color; fill:none; stroke-width:$stroke\" />\n"; $paths.="</a>\n"; break; case "point": $text=dynamapGetRawText(trim($command[1]),$cur); $alt_text.=$text.' '; $mtitle=Title::newFromURL(trim($command[1])); $link=$mtitle->getDBKey(); $pos=0; $coords=explode('|',dynamapFindTemplate($text,'{{coor',$pos)); $mode=trim(array_shift($coords)); $px=0; $py=0; $first=true; while(count($coords)>=4) { $y=trim(array_shift($coords)); if(strtoupper(trim(array_shift($coords)))=='S') $y*=-1; $x=trim(array_shift($coords)); if(strtoupper(trim(array_shift($coords)))=='W') $x*=-1;
dynamapProject($x,$y,$px,$py,$w,$h,$minlat,$minlong,$maxlat,$maxlong); $paths.="<a xlink:href=\"/index.php/$link\">"; $paths.="<circle cx=\"$px\" cy=\"$py\" r=\"$radius\" style=\"fill:$color; stroke:none\" />\n"; $px+=$radius; $py-=$radius; $paths.="<text x=\"$px\" y=\"$py\" style=\"fill:$textcolor; stroke:none\" >".trim($command[1])."</text></a>\n"; } break; } } }
$res=fopen($outfilenamebase.'.svg','w');
$buffer = <<<EOH1 <?xml version="1.0" encoding="iso-8859-1" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="$w" height="$h">
<defs>
<style type="text/css"> <![CDATA[ path.level0 {fill: #9EC7F3; stroke: #9EC7F3; stroke-width:3 } path.level1 {fill: #FFFFD0; stroke: #4090D0; stroke-width:1 } path.level2 {fill: #9EC7F3; stroke: #4090D0; stroke-width:1 } path.level3 {fill: #FFFFD0; stroke: #4090D0; stroke-width:1 } path.level4 {fill: #9EC7F3; stroke: #4090D0; stroke-width:1 }
$css
]]> </style> </defs> <path class="level0" d="M 0 0 L $w 0 L $w $h L 0 $h L 0 0" />
EOH1;
fwrite($res,$buffer); fwrite($res,$paths); fwrite($res,"</svg>\n"); fclose($res);
exec("rsvg $outfilenamebase.svg $outfilenamebase.png");
# return '<img src="/'.$outfilenamebase.'.png">
<a href="/wiki/'.$outfilenamebase.'.svg">SVG version with clickable links</a>'; return '<object data="/'.$outfilenamebase.'.svg" width="'.$w.'" height="'.$h.'" type="image/svg+xml"><img src="/'.$outfilenamebase.'.png" width="'.$w.'" height="'.$h.'" border="0">
<a href="/'.$outfilenamebase.'.svg">SVG version with clickable links</a></object>'; }
?>