User:Dschwen/Dynamap

From Wikipedia, the free encyclopedia

<?php

  1. Dynamap WikiMedia extension
  2. introduces
  3. * <dynamap></dynamap> Tags
  4. * Special:DynamapConstants
  5. Note: The output is not interpreted as WikiText but directly
  6. included in the HTML output. So Wiki markup is not supported.
  7. To activate the extension, include it from your LocalSettings.php
  8. 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" );

$out = "

[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>'; }

?>