User:George Drummond/SpecialGoogleEarth.php

From MediaWiki.org
Jump to: navigation, search
THIS IS AN ALPHA RELEASE.
<?php 
/*
 * Google Earth Exporter for Google Maps Extension
 * http://www.mediawiki.org/wiki/Extension:Google_Maps
 * Written for Wikipaddle.org
 *
 * Copyright (c) 2006 by George Drummond, georgedrummond@wikipaddle.org
 *
 * Expanding Google Maps Extension by Evan Miller, emmiller@gmail.com
 *
 * Version 0.1 ALPHA - 2 Feb 2007
 *
 * -----------------------------------------------------------------------
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * http://www.gnu.org/copyleft/gpl.html
 * -----------------------------------------------------------------------
 */
 
if(!defined('MEDIAWIKI'))
   die('This is not a stand alone file ;)');
 
/*
 *
 * Define the defaults
 *
 */
define ('GME_DEFAULT_ICON', 'http://maps.google.com/mapfiles/kml/pal4/icon57.png');
define ('GME_ICON_PATH', 'http://maps.google.com/mapfiles/kml/pal2/');
define ('GME_POLYLINE_OPACITY', '7f');
define ('GME_POLYLINE_WIDTH', '4');
define ('GME_EXPORT_VERSION', '0.1 ALPHA');
 
/*
 *
 * Special page stuff
 *
 */
$wgExtensionFunctions[] = 'GoogleEarthExportSetup';
$wgExtensionCredits['specialpage'][] = array(
   'name' => 'Google Earth Export',
   'author' => '[http://wikipaddle.org/wiki/User:George_Drummond George Drummond]',
   'version' => GME_EXPORT_VERSION,
   'url' => 'http://www.mediawiki.org/wiki/Extension:Google_Maps',
   'description' => 'Google earth exporter for GoogleMaps plugin'
);
 
function GoogleEarthExportSetup( $par = '' ) {
        global $wgMessageCache;
        SpecialPage::addPage(new SpecialPage('GoogleEarthExport', '', true, 'GoogleEarthExportSpecial', true));
        $titleObj = Title::makeTitle( NS_SPECIAL, 'GoogleEarthExport' );
        $action = $titleObj->escapeLocalURL();
        $wgMessageCache->addMessages( 
                array(
                        "googleearthexport"  => "Google Earth Export",               
                        "ge-title" => "Google Earth Exporter for Google Maps",
                        "ge-pagenoexist" => "=== We couldnt find the page that you requested ===",
                        "ge-nomapfound" => "=== We couldn't find a map on the page that you requested ===",
                        "ge-formdescription" => "To export a google map to google earth format, enter the '''page name''' into the box bellow and press export.",
                        "ge-form" => "<form method=\"get\" action=\"$action\"><input name=\"page\" type=\"text\" /> <input name=\"export\" type=\"submit\" value=\"Export\" /></form><br />",
                        "ge-information" => "'''This is a alpha version and is currently still being tested and developed.'''",
                )
        );
 
}
 
function GoogleEarthExportSpecial(){
        global $wgRequest;
        $page_name = textSqlSafe( $wgRequest->getText( 'page', $par ) ); // Make input safe to put in SQL. ***THIS MIGHT BECOME A PROBLEM WITH PAGES WITH STRANGE NAMES?**
        if( $page_name != "" ){
                $page_name = str_replace(" ", "_", $page_name); // Replace spaces in page name with "_"
                GoogleEarthExporter( $page_name );
        }
        else { GoogleEarthForm(); } // If no page requested just show form
}
 
function GoogleEarthForm(){
        global $wgOut;
        $wgOut->addWikiText( wfMsg( 'ge-formdescription') );
        $wgOut->addHTML( wfMsg( 'ge-form' ) ); 
        $wgOut->addWikiText( wfMsg( 'ge-information' ) );
}
 
/*
 *
 * SQL Functions
 *
 */
function pageFromTitle( $title ) {
        return "page_namespace= '".$title->getNamespace()."' AND page_title= '".$title->getDbKey()."'" ;
}
 
function pageByName2( $name ) {
        $title = Title::newFromText( $name );
        if( is_null( $title ) ) {
                return new WikiError( "Can't export invalid title" );
        } else {
                return pageFromTitle( $title );
        }
}
 
function pageByTitle( $title ) { // Not in current use
        return $this->dumpFrom('page_namespace=' . $title->getNamespace() .
        ' AND page_title=' . $this->db->addQuotes( $title->getDbKey() ) );
}
 
 
function textSqlSafe( $value ){ // Make text safe to form sql query.
        if( get_magic_quotes_gpc() )
                  $value = stripslashes( $value );
        if( function_exists( "mysql_real_escape_string" ) )
                  $value = mysql_real_escape_string( $value );
        else
                  $value = addslashes( $value );
        return $value;
}
 
/*
 *
 * Pull page from database
 *
 */
function GoogleEarthExporter( $page_name ){
        global $wgRequest, $wgExportAllowListContributors;
        global $wgExportAllowHistory;
 
        $dbr =& wfGetDB( DB_SLAVE );
        $page = $dbr->tableName( 'page' );
        $revision = $dbr->tableName( 'revision' );
        $text = $dbr->tableName( 'text' );
 
        $page_title = pageByName2( $page_name );
 
        // Could this SQL could do with some cleaning up?
        $geSqlSelect = "SELECT page_namespace, page_title, page_id, page_latest, old_text";
        $geSqlSelectFrom = " FROM $page, $revision, $text";
        $geSqlWhere = " WHERE $page_title AND page_id=rev_page AND page_latest=rev_id AND rev_text_id=old_id";
        $geSqlOrderby = ' ORDER BY page_id';
        $sql = $geSqlSelect.$geSqlSelectFrom.$geSqlWhere.$geSqlOrderby;
 
        $res = $dbr->query( $sql );
        $row = $dbr->fetchObject( $res );
 
        if( !$row->page_title ) // If page dosen't exist
                pageNotExist();
        elseif( isRedirect( $row->old_text ) ) // If it is a redirect
                handleRedirects( $row->old_text, $page_name );
        else 
                makeKml( $row->page_title, $row->old_text );  // If page exists and isnt a redirect go to makeKml
}
 
/*
 *
 * Page errors
 *
 */
function pageNotExist(){
        global $wgOut;
        $wgOut->addWikiText( wfMsg( 'ge-pagenoexist' ) );
        GoogleEarthForm();
}
 
function isRedirect( $old_text ){ // Check if page is a redirect
        if(preg_match('/#REDIRECT \[\[([^<]*)\]\]/', $old_text, $new))
                return true;
}
 
function handleRedirects( $old_text, $page_title ){
        preg_match('/#REDIRECT \[\[([^<]*)\]\]/', $old_text, $redirect);
        if($page_name == $redirect[1])
                echo "double redirect";
        else{
                $titleObj = Title::makeTitle( NS_SPECIAL, 'GoogleEarthExport' );
                $url = $titleObj->escapeLocalURL();
                header("Location: ".$url."?page=".$redirect[1]);
        }
}
 
/*
 *
 * Rendering wiki text. See hacky link fixers, know any better way feel free to change.
 *
 */
function renderWikiText( $text ){ // This code was taken from somewhere but i forgot source.
        global $wgOut, $wgUser, $wgTitle, $wgParser, $wgServer, $wgAllowDiffPreview, $wgEnableDiffPreviewPreference;
        $parserOptions = ParserOptions::newFromUser( $wgUser );
        $parserOptions->setEditSection( false );
        $parsed = $wgParser->parse( $text, $wgTitle, $parserOptions ); 
        $output = str_replace('<img src="/', '<img src="'.$wgServer.'/', $parsed->mText); // Image link fix
        $output = str_replace('<a href="/', '<a href="'.$wgServer.'/', $output); // Url link fix
        return $output;
}
 
/*
 *
 * Map Making stuff
 *
 */
function mime_type( $page_title ){
        $output .= header("Cache-Control: no-cache, must-revalidate"); // We dont want file to be cached.
        $output .= header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");   // Expires in the past.
        $output .= header("Content-type: application/vnd.google-earth.kml+xml");
        $output .= header('Content-Disposition: attachment; filename="'.$page_title.'.kml"');
        return $output;
}
 
function xml_header( $page_title ){
        global  $wgServer, $wgVersion;
        $output = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
        $output .= "<kml xmlns=\"http://earth.google.com/kml/2.1\">\n";
        $output .= "<!-- Source: ".$wgServer.", Generated by Special:GoogleEarthExport -->\n"; // This might be usefull when trying to debug
        $output .= "<!-- Page: ".$page_title.", Mediawiki: ".$wgVersion.", Version: ".GME_EXPORT_VERSION.", Time: ".date('Y-m-d, H:i:s')." -->\n";
        $output .= "<Document>\n<open>1</open>\n";
        return $output;      
}
 
function addMarker( $lat, $lon, $icon, $description, $marker_count ) {
        $output .= "<Placemark>\n";
        $output .= "<name>point ".$marker_count."</name>";
        $output .= "<Style><Icon><href>";
        if 
                ($icon) $output .= GME_ICON_PATH.$icon."png";
        else 
                $output .= GME_DEFAULT_ICON;
        $output .= "</href></Icon></Style>\n";
        $output .= "<Point><coordinates>".$lon.", ".$lat.", 0</coordinates></Point>\n";
        if ($description) 
                $output .= '<description><![CDATA[<table width="333">'.$description.'</table>]]></description>';
        $output .= "</Placemark>\n";
        return $output;
}
 
function addPolyline( $polyline, $color ){
        $output .= "<Placemark>\n<name>Polyline</name>\n<Style><LineStyle>
                                <color>".GME_POLYLINE_OPACITY.ltrim($color, "#")."</color>
                                <width>".GME_POLYLINE_WIDTH."</width>      
                                </LineStyle></Style><LineString><tessellate>1</tessellate><altitudeMode>clampedToGround</altitudeMode>\n"; //Might want to change this later on.
        $output .= "<coordinates>\n";
        $output .= implode("\n", $polyline);
        $output .= "\n</coordinates>\n</LineString>\n</Placemark>\n";
        return $output;
}
 
/*
 *
 * Map maker, taken from google maps extension
 *
 */
function makeMap( $map ) {
        $lines = preg_split("/[\r\n]+/", $map);
        $doAddMarker = false;
        $marker_count = 0; // Just name markers numerically for now, starting at 1
        foreach($lines as $line) {
                if (preg_match("/^(#[0-9a-fA-F]{6})/", $line, $matches)) {
                        //if ($wgGoogleMapsEnablePaths) {
                                if (isset($color)) { // i.e., we were just making a path, so dump and reset $polyline
                                        $output .= addPolyline($polyline, $color);
                                        $polyline = array();
                                }
                                $color = $matches[1];
                        //}
                }
                elseif (preg_match('/^\/([^\\\\]+)\\\\ *(.*)$/', $line, $matches)) {
                        $tab_description = renderWikiText( $matches[2] );
                        $description .="<hr /><h2>".$matches[1]."</h2>".$tab_description;
                        $doAddMarker = true; // we want a marker there if it has tabs
                } 
                elseif (preg_match("/^(?:\(([.a-zA-Z0-9_-]*?)\) *)?([^,]+), *([^ ,]+)(?:, (.+))?/", $line, $matches)) {
                        if ($doAddMarker) { // first create the previous marker, now that we have all the tab/caption info
                                $output .= addMarker($lat, $lon, $icon, $description, $marker_count);
                                $doAddMarker = false;
                        }
                        $icon = $matches[1];
                        $lat = $matches[2];
                        $lon = $matches[3];
                        $description = addslashes(renderWikiText($matches[4]));
                        // This parse function above lets us insert wiki markup into the map markers.
                        //}
                        if (is_numeric($lat) && is_numeric($lon)) {
                                if ($icon || $caption || !isset($color)) { // we don't actually put down a marker for anonymous points along a path
                                        $doAddMarker = true;
                                        $marker_count++;
                                }
                                // If we're making a path, record the location and move on.
                                if (isset($color)) {
                                        $polyline[] = "{$lon}, {$lat}";
                                }
                        }
                }
        }
        if( isset($color) ) // Close polylines
                $output .= addPolyline( $polyline, $color );
        if ($doAddMarker) { // we've been waiting
                                $output .= addMarker($lat, $lon, $icon, $description, $marker_count);
        }
 
        return $output;
}
 
/*
 *
 * KML maker
 *
 */
function makeKml( $page_title, $old_text ){
        global $wgOut, $wgRequest;
        if(preg_match("/(<googlemap[^>]*>)([^<]*)(<\/googlemap>)/", $old_text)){
 
                preg_match_all("/<googlemap([^>]+)>*([^<]+)<\/googlemap>/", $old_text, $source);
                $maps = $source[2];
                $maps_attributes = $source[1];
                $map_number = $wgRequest->getText( 'map_number', $par );
 
                $output = "";
                $output .= xml_header( $page_title );
 
                if( $map_number != "" && is_numeric($map_number) && $map_number <= count($maps) ) {
                        $output .= makeMap( $maps["$map_number"] );
                }
                elseif( !$map_number ){ // if no map is requested then just display all
                        $i = 0; // Maps dont have any title at the moment. Lets just label them numerically for now, starting at 1.
                        foreach($maps as $map){
                                preg_match("#name=\"(.*?)\"#s",$maps_attributes[$i], $title_tag);
                                if( $title_tag[0] = "" || !$title_tag[0] ){
                                        $title = "Map ".($i+1);
                                }
                                else { $title = $title_tag[1]; }
                                $output .= "<Folder>\n<name><![CDATA[".$title."]]></name>\n";
                                $output .= makeMap( $map );               
                                $output .= "</Folder>";
                                $i++;
                        }
                }
                else {// Map number isnt found on this page.
                        $wgOut->setPageTitle( wfMsg( 'ge-title' ) ); // If no map is found on page
                        $wgOut->addWikiText( "=== We couldn't find that map number on the page that you requested ===" );
                        GoogleEarthForm();
                        return true;
                }
                $output .= "</Document>\n";
                $output .= "</kml>";
 
                // Output mime type now
                $wgOut->disable();
                mime_type( $page_title );
                echo $output;
        }
        else {
                $wgOut->setPageTitle( wfMsg( 'ge-title' ) ); // If no map is found on page
                $wgOut->addWikiText( wfMsg( 'ge-nomapfound' ) );
                GoogleEarthForm();
        }
}
Personal tools
Namespaces
Variants
Actions
Site
Support
Download
Development
Communication
Print/export
Toolbox