allwiki首页  
天下维客 你可以修改的网络知识库
首页最近更改优秀条目专题展示电脑科技词典软件学习网络知识电脑安全明星时尚天下百科
 

51ditu Google Maps Extension

天下维客,你可以修改的网络知识库

Jump to: navigation, search

目录

实现效果

Ditubz08.png Image:Ditubz08.png Ditubz09.png

说明

源文件

  • 在mediawiki网站的插件目录建立GoogleMaps的文件夹(包含以下1-7个文件),第8个文件的存放位置请修改第2个文件指定。

1、EditorsMap.js

 // almost-100% GUI Google Maps Builder for MediaWiki.
// Copyright 2006 Evan Miller, except as noted below.

// Man, this almost looks professional.

/*
 * Hello! Welcome to the source of the Editor's Map. This is broken down
 * into four classes:
 *
 * 1. EditorsMarker: a wrapper around the GMarker path that provides the
 *            references necessary for the linked list structures, as well
 *            as information about captions and tabs
 * 2. EditorsSingletons: a linked list of unaffiliated markers
 * 3. EditorsPath: a linked list representing a path of connected markers
 * 4. EditorsMap: the Big One. This is the application class that contains
 *            everything else.
 *
 * You'll also notice references to a hash called "_". That's a structure of
 * messages created by GoogleMapsMessages.php.
 *
 * Anyway, feel free to poke around. I put a lot of work into cleaning and
 * documenting this code so you can understand it. If you make improvements,
 * please take time to send me a patch, so the program is better for everyone.
 * You can reach me at emmiller@gmail.com. Thanks!
 *
 */

// TODO: make path joints draggable only in "edit this path" mode for performance.

// "Class" is taken from the Prototype library. This makes it so we can
// declare new classes with arguments, instead of having to
// call the initialize method ourselves.

var Class = { create: function() { return function() { this.initialize.apply(this, arguments); } } };

// The application object.
var emap;

// Used for measuring paths.
var conversion_factor = { 'meters':1, 'miles': 100 / 2.54 / 12 / 5280 };
var decimal_places = { 'meters':0, 'miles':2 };

// a wrapper around the GMarker class
// This adds the variables we need to play with
// EditorsPath, which also makes it easier
// for us to swap out the underlying GMarker.
var EditorsMarker = Class.create();
EditorsMarker.prototype = {
    initialize: function(gmarker, emap) {
                  // one day I'm going to buy a leather jacket that says
                  // "F*ck the DOM" on the back of it, and wear it in public.
                  this.container = document.createElement("span");
                  this.container.appendChild(document.createTextNode(emap.round(gmarker.getPoint().lat())+', '+emap.round(gmarker.getPoint().lng())));
                  this.container.appendChild(document.createElement("br"));
                  this.gmarker = gmarker;
                  this.gmarker.emarker = this;
                  this.emap = emap;
                  this.tabs = new Array();
                  var this_marker = this;
                  GEvent.addListener(this.gmarker, 'dragend', function() { this_marker.updateLocation() } );
                },

    getIcon: function() {
	       return this.gmarker.getIcon();
	     },

    setCaption: function(caption) {
		  if (caption && this.getIcon() == GME_SMALL_ICON ) {
		    this.setIcon(G_DEFAULT_ICON);
		  } else if (!caption && this.path && this.getIcon() == G_DEFAULT_ICON) {
		    this.setIcon(GME_SMALL_ICON);
		  }
		  this.caption = caption;
          this.dump();
		},

    dump: function() {
            this.container.innerHTML = '';
            var line = '';
            if (this.icon_name)
              line += '('+this.icon_name+') ';
            line += this.emap.round(this.getPoint().lat())+', '+this.emap.round(this.getPoint().lng());
            if (this.caption)
              line += ', '+this.caption;
            this.container.appendChild(document.createTextNode(line));
            this.container.appendChild(document.createElement('br'));
            for(var i=0;i<this.tabs.length;i++) {
              this.container.appendChild(document.createTextNode('/'+this.tabs[i].title+"\\ "+this.tabs[i].content));
              this.container.appendChild(document.createElement('br'));
            }
          },

    addTab: function(title, content) {
              this.tabs[this.tabs.length] = { 'title':title, 'content':content };
              if (this.getIcon() == GME_SMALL_ICON)
                this.setIcon(G_DEFAULT_ICON);
              this.dump();
            },

// The API doesn't let us change a marker's icon on the fly,
// so we need to instantiate a new GMarker. No problem, though,
// because all the references that this application uses are
// here in the wrapper class.
    setIcon: function(icon) {
	       this.emap.zapGMarker(this.gmarker);
	       this.gmarker = new GMarker(this.gmarker.getPoint(), { 'icon':icon, 'draggable':this.gmarker.draggable() });
	       this.emap.gmap.addOverlay(this.gmarker);
	       this.gmarker.emarker = this;
	       var this_marker = this;
	       GEvent.addListener(this.gmarker, 'dragend', function() { this_marker.updateLocation() } );
	     },

    getPoint: function() {
                return this.gmarker.getPoint();
	      },

    distanceFrom: function(marker) {
                    return this.getPoint().distanceFrom(marker.getPoint());
                  },

// Called at the end of a drag. We recalculate the
// path's distance and draw new Polyline segments.
    updateLocation: function() {
      if (this.incoming_polyline) {
	  var prev = this.incoming_polyline.getVertex(0);
	  this.path.distance -= prev.distanceFrom(this.incoming_polyline.getVertex(1));
	  this.path.distance += prev.distanceFrom(this.getPoint());
	  this.path.gmap.removeOverlay(this.incoming_polyline);
	  var newpline = new GPolyline([ prev, this.getPoint() ],
		  this.path.color, this.path.weight, this.path.opacity);
	  this.incoming_polyline = newpline;
	  this.previous_marker.outgoing_polyline = newpline;
	  this.path.gmap.addOverlay(newpline);
      }
      if (this.outgoing_polyline) {
	  var nex = this.outgoing_polyline.getVertex(1);
	  this.path.distance -= nex.distanceFrom(this.outgoing_polyline.getVertex(0));
	  this.path.distance += nex.distanceFrom(this.getPoint());
	  this.path.gmap.removeOverlay(this.outgoing_polyline);
	  var nextpline = new GPolyline([ this.getPoint(), nex ],
		  this.path.color, this.path.weight, this.path.opacity);
	  this.outgoing_polyline = nextpline;
	  this.next_marker.incoming_polyline = nextpline;
	  this.path.gmap.addOverlay(nextpline);
      }
      this.dump();
      this.emap.dumpPaths();
    },

		    // we need this logic in a couple places, so might as well put it here.
    getBalloonFooter: function() {
      var message = '<a href="javascript:emap.updateActiveMarker()">'+_['save point']+'</a>'+
	  '<a href="javascript:emap.removeActiveMarker()">'+_['remove']+'</a>';
      if (GME_PATHS_SUPPORTED && this.path == undefined) {
	  message += '<a href="javascript:emap.startPath()">'+_['start path']+'</a>';
      }
      message += '<div style="color: #aaa; font-size: 10px;">'+
	  this.emap.round(this.getPoint().lat())+', '+
	  this.emap.round(this.getPoint().lng())+'</div>';
      return message;
    },

    openEditWindow: function() {
      if (this.tabs.length) {
	  var tabs = [];
	  for(var t=0; t < this.tabs.length; t++) {
              label = this.emap.rtl ? ((parseInt(t)+1)+' '+_['tab']) : _['tab']+' '+(parseInt(t)+1);
              content = _['tab title']+':<br />'+'<input size="24" id="tab_title_'+t+'" value="'+this.tabs[t].title+'" />'+
		      '<br />'+_['caption']+':<br />'+
		      '<textarea class="balloon_textarea" id="tab_content_'+t+'">'+
		      this.tabs[t].content+'</textarea><br />'+
		      this.getBalloonFooter();
              if (this.emap.rtl) {
                  content = '<div style="direction: rtl;">'+content+'</div>';
              }
              tabs[t] = new GInfoWindowTab( label, content );
	  }
	  this.gmarker.openInfoWindowTabsHtml(tabs);
      } else {
          content = _['make marker']+'<br /><textarea id="balloon_textarea" class="balloon_textarea">'+
                      ((this.caption == undefined) ? '' : this.caption)+
                      '</textarea><br />'+this.getBalloonFooter();
          if (this.emap.rtl) {
              content = '<div style="direction: rtl;">'+content+'</div>';
          }
          this.gmarker.openInfoWindowHtml( content, { maxWidth:270 });
      }
    }
};

// It's: a very simple linked list
var EditorsSingletons = Class.create();
EditorsSingletons.prototype = {
    initialize: function() {
                  this.container = document.createElement("span");
                  document.getElementById("map_dump_body").appendChild(this.container);
                },

    reset: function() {
             this.head = undefined;
             this.container = document.createElement("span");
             document.getElementById("map_dump_body").appendChild(this.container);
           },

    removeMarker: function(doomed_marker) {
            if (!doomed_marker) {
              return;
            }
            var p = this.head;
            // First, remove it from the singletons' linked list.
            while(p) {
              if (p == doomed_marker) {
                if (p.previous_marker) {
                  p.previous_marker.next_marker = p.next_marker;
                }
                if (p.next_marker) {
                  p.next_marker.previous_marker = p.previous_marker;
                }
                this.container.removeChild(doomed_marker.container);
              }
              p = p.previous_marker;
            }

            // If we're removing the head of the list, update
            // the head reference
            if (this.head == doomed_marker) {
              this.head = doomed_marker.previous_marker;
            }

            doomed_marker.previous_marker = undefined;
            doomed_marker.next_marker = undefined;
                  },

    addMarker: function(marker) {
	     marker.previous_marker = this.head;
	     if (this.head) { this.head.next_marker = marker; }
	     this.head = marker;
         this.container.appendChild(marker.container);
	   }
};

// A slightly more complicated linked list. This object also stores
// information about the path, such as its color and total distance.
var EditorsPath = Class.create();
EditorsPath.prototype = {
    initialize: function(color, map, units) {
          this.container = document.createElement("span");
          this.container.appendChild(document.createTextNode(''));
          this.container.appendChild(document.createElement('br'));
          document.getElementById("map_dump_body").appendChild(this.container);
	      this.colorSelector = new color_select(color);
	      this.setColor(color);
	      this.gmap = map;
	      this.units = units;
	      this.weight = 6;
	      this.size = 0;
	      this.distance = 0;
	    },

    addMarker: function(marker) {
  // Add mutual references
	     var polyline;
	     marker.path = this;
	     if (this.head != undefined) {
	       this.distance += this.head.distanceFrom(marker);
	       // add the polyline
	       polyline = new GPolyline([ this.head.getPoint(), marker.getPoint() ], this.color, this.weight, this.opacity);
	       this.head.outgoing_polyline = polyline;
	       marker.incoming_polyline = polyline;
	       marker.previous_marker = this.head;
	       this.head.next_marker = marker;

	       this.gmap.addOverlay(polyline);
         }
         this.head = marker;
         this.size++;
         this.container.appendChild(marker.container);
       },

// 1. remove the marker's references
// 2. update its reference's references
// 3. recreate polylines
// 4. update distance
    removeMarker: function(doomed_marker) {
		var p = this.head;
		while(p) {
		  if (p == doomed_marker) {
		    if (p.previous_marker && p.next_marker) { // from the middle
		        this.distance = this.distance -
                    p.distanceFrom(p.previous_marker)-
                    p.distanceFrom(p.next_marker) +
                    p.previous_marker.distanceFrom(p.next_marker);
                p.previous_marker.next_marker = p.next_marker;
                p.next_marker.previous_marker = p.previous_marker;
                this.gmap.removeOverlay(p.outgoing_polyline);
                this.gmap.removeOverlay(p.incoming_polyline);
                var newpline = new GPolyline([ p.previous_marker.getPoint(), p.next_marker.getPoint() ],
                        this.color, this.weight, this.opacity);
                p.previous_marker.outgoing_polyline = newpline;
                p.next_marker.incoming_polyline = newpline;
                this.gmap.addOverlay(newpline);
		    } else if (p.previous_marker && !p.next_marker) { // the head
		      this.distance -= p.distanceFrom(p.previous_marker);
		      this.head = p.previous_marker;
		      p.previous_marker.outgoing_polyline = undefined;
		      p.previous_marker.next_marker = undefined;
		      this.gmap.removeOverlay(doomed_marker.incoming_polyline);
		    } else if (!p.previous_marker && p.next_marker) { // the tail
		      this.distance -= p.distanceFrom(p.next_marker);
		      p.next_marker.previous_marker = undefined;
		      p.next_marker.incoming_polyline = undefined;
		      this.gmap.removeOverlay(p.outgoing_polyline);
		    }
		  }
		  p = p.previous_marker;
		}
		doomed_marker.previous_marker = undefined;
		doomed_marker.next_marker = undefined;
		doomed_marker.path = undefined;
		this.size--;
                this.container.removeChild(doomed_marker.container);
		return doomed_marker.gmarker;
	      },

    distanceExpression: function() {
		      return Math.round(this.distance *
			      conversion_factor[this.units] *
			      Math.pow(10, decimal_places[this.units])) /
			  Math.pow(10, decimal_places[this.units])+' '+_[this.units];
			},

    setColor: function(color) {
	      this.hex_color = color;
	      var normalized = this.hex2alpha(color);
	      this.color = normalized[0];
	      this.opacity = normalized[1];
          this.container.childNodes[0].nodeValue = this.hex_color;
	  },

// This method treats whiteness as transparency,
// returning a renormalized hex value and the
// opacity level. Works well for the "map" view,
// not so well for others. Might need to do something
// different for the satellite imagery, in the future...

// Aren't you amazed how short this function is? I am,
// considering this is JavaScript.
    hex2alpha: function(hex) {
                 hex = hex.replace(/#/, '');
                 hex = hex.toUpperCase();
                 var rgb = [ parseInt(hex.substring(0, 2), 16),
                     parseInt(hex.substring(2, 4), 16),
                     parseInt(hex.substring(4, 6), 16) ];
                 var lets = "0123456789abcdef".split('');
                 var min = 255;
                 for(var i=0; i<rgb.length; i++) {
                   if (rgb[i] < min) {
                     min = rgb[i];
                   }
                 }
                 for(var i=0; i<rgb.length; i++) {
                   // re-normalize
                   rgb[i] = (rgb[i] - min) * (256 / (256 - min));
                   // hexify
                   rgb[i] = lets[rgb[i] >> 4] + lets[rgb[i] & 0xf];
                 }
                 return( [ '#'+rgb.join(''), (256 - min) * 1.0 / 256 ] );
               },

// Here we walk along the EditorsPath and update each segment.
    updateColor: function(new_color) {
                   this.setColor(new_color);
                   var m = this.head;
                   while(m) {
                     if (m.incoming_polyline) {
                       var newpline = new GPolyline([ m.incoming_polyline.getVertex(0), m.incoming_polyline.getVertex(1) ],
                               this.color, this.weight, this.opacity);
                       this.gmap.removeOverlay(m.incoming_polyline);
                       this.gmap.addOverlay(newpline);
                       m.incoming_polyline = newpline;
                       m.previous_marker.outgoing_polyline = newpline;
                     }
                     m = m.previous_marker;
                   }
                 }
};

var EditorsMap = Class.create();
EditorsMap.prototype = {

/********* Initialization *********/

    initialize: function(options) {
// There are some weird incompatibilities with Safari which
// make the Editor's Map about 50% broken.
// If you want to be a hero and debug Safari's problems,
// just change this condition and start playing with it.
// For now, I'm declaring it incompatible.
	if (!GBrowserIsCompatible() || navigator.vendor == "Apple Computer, Inc.") {
	    var message_div = document.createElement('div');
	    message_div.innerHTML = _['no editor'];
	    document.getElementById(options.container).appendChild(message_div);
	    return;
	}
          // Initialize
	this.icon_base = options.icons;
	this.precision = options.precision; // how many decimal places?
	this.paths_supported = GME_PATHS_SUPPORTED;
	this.default_color = options.color;
	this.paths = new Array();
	this.units = options.units;
        this.rtl = options.rtl;
	this.toggle_link = document.getElementById(options.toggle);
	this.textbox = document.getElementById(options.textbox);
	this.defaults = options; // keep a copy for later

	this.mother_div = this.getEditorsMapNode(options); // build all the HTML

	// stick it somewhere useful
	document.getElementById(options.container).appendChild(this.mother_div);

	this.singletons = new EditorsSingletons();

	// Now make the API components and attach to the appropriate places.
	this.gmap = new GMap2(this.map_div);
	this.controls = { 'selector':new GMapTypeControl(), 'scale':new GScaleControl(), 'overview':new GOverviewMapControl() };
	this.active_controls = {};

	if (options.geocoder) {
	    this.geocoder = new GClientGeocoder();
	}
	if (options.localsearch) {
	    this.localSearch = new GlocalSearch();
	    this.localSearch.setCenterPoint(this.gmap);
	    this.localSearch.setSearchCompleteCallback(this, EditorsMap.prototype.populateResults);
	}

	this.toggle_link.style.display = "";

	this.configureMap( options );

	if (this.maps_in_article == 1)
	    this.loadMap(1);

	// Closures are great, but they make it harder to have short-ish functions.
	// Here's how we cheat and let the closure bind to "this" but stick the workhorse
	// function somewhere else.
	var this_map = this;

	// Keep the map's center up-to-date.
	GEvent.addListener(this.gmap, 'moveend', function() { this_map.dumpMapAttributes() });

	// one click listener to rule them all...
	GEvent.addListener(this.gmap, 'click', function(overlay, point) { this_map.clickMap(overlay, point); });
    },

    getEditorsMapNode: function(options) {
          // Crack your knuckles. It's time to build a big fat DOM node with everything you see.
	       this.map_div = document.createElement("div");
	       this.map_div.style.width = options.width+"px";
	       this.map_div.style.height = options.height+"px";
               this.map_div.style.direction = "ltr";

               this.search_div = document.createElement("div");
	       if (options.geocoder || options.localsearch) {
                   if (options.localsearch) {
                       this.search_div.innerHTML = _['search preface'];
                   } else {
                       this.search_div.innerHTML = _['geocode preface'];
                   }
                   this.search_div.innerHTML +=
		       '<br /><input type="text" size="40" id="address_input" onkeypress="emap.findAddressIfEnter(event)" />'+
		       '<a href="javascript:emap.findAddress();">'+_['search']+'</a>'+
		       '<a href="javascript:emap.clearResults()" id="clear_search_results" style="display: none;">'+
		       _['clear search']+'</a>';
                   this.searching_div = document.createElement("div");
                   this.searching_div.innerHTML = _['searching'];
                   this.searching_div.style.display = 'none';
	       } else {
                   this.search_div.innerHTML = _['no search preface'];
               }

	       if (options.localsearch) {
		   this.map_table = document.createElement("table");
		   this.map_table.setAttribute("cellspacing", "8");
		   this.map_table.style.display = 'none';

		   this.map_body = document.createElement("tbody");

		   this.local_search_results = document.createElement("tr");

		   this.map_table.appendChild(this.map_body);
		   this.map_body.appendChild(this.local_search_results);
	       }

	       // We need to hang on to this reference for later,
	       // so this is scoped for the object, not just the initializer
	       this.load_map_div = document.createElement("div");
	       this.load_map_div.style.padding = "10px 0px";
	       this.refreshMapList();

	       this.path_info_div = document.createElement("div");
	       this.path_info_div.style.padding = "15px 0px";

	       this.instructions_div = document.createElement("div");
	       this.instructions_div.innerHTML = '<p>'+_['instructions']+'<a href="javascript:if(confirm(\''+_['are you sure']+'\')) { emap.clearMap(); }">'+_['clear all points']+'</a></p>';

	       this.map_dump_div = document.createElement("pre");

	       this.map_dump_attributes_div = document.createElement("span");
	       this.map_dump_body_div = document.createElement("span");
	       this.map_dump_body_div.setAttribute("id", "map_dump_body");

	       this.map_dump_div.appendChild(this.map_dump_attributes_div);
	       this.map_dump_div.appendChild(this.map_dump_body_div);
	       this.map_dump_div.appendChild(document.createTextNode('</googlemap>'));

	       this.note_div = document.createElement("div");
	       this.note_div.style.padding = "10px";
	       this.note_div.style.fontWeight = 'bold';
	       this.note_div.style.fontStyle = 'italic';
	       this.note_div.innerHTML = _['note'];

	       this.root_div = document.createElement("div");
	       this.root_div.setAttribute('id', 'mother_div');

               this.root_div.appendChild(this.search_div);

               if (this.searching_div) {
                   this.root_div.appendChild(this.searching_div);
               }
               if (this.map_table) {
                   this.root_div.appendChild(this.map_table);
               }

	       this.root_div.appendChild(this.path_info_div);
	       this.root_div.appendChild(this.map_div);
	       this.root_div.appendChild(this.getControlPanelNode());
	       this.root_div.appendChild(this.instructions_div);
	       this.root_div.appendChild(this.map_dump_div);
	       this.root_div.appendChild(this.note_div);
	       this.root_div.appendChild(this.load_map_div);
	       return this.root_div;
    },

    getControlPanelNode: function() {
		  /* of course, at some point, DOM methods are more pain than they're worth.
           That's when innerHTML comes to the rescue. (I like to think of it as the
           literal syntax for DOM objects.) */
          var control_panel_div = document.createElement("div");
		  control_panel_div.style.fontSize = "10px";
          var text_sep = ''+
              ''+
              ''+
              '';
		  var html = _['zoom control']+': '+
              this.getRadioOption('controls', 'large', _['large'])+
              this.getRadioOption('controls', 'medium', _['medium'])+
              this.getRadioOption('controls', 'small', _['small'])+
              this.getRadioOption('controls', 'none', _['no zoom control'])+
              ''+
              ''+
              ''+
		      _['width']+': '+
		      '<select id="select_width" onchange="emap.configureMap({\'width\':this.value})">'+
              '<option></option>';
          for(var i=50;i<=700;i+=25)
		      html += '<option value="'+i+'">'+i+'</option>';
		  html += '</select>'+
		      ''+
		      ''+
		      _['height']+': '+
		      '<select id="select_height" onchange="emap.configureMap({\'height\':this.value})">'+
              '<option></option>';
          for(var i=50;i<=600;i+=25)
		      html += '<option value="'+i+'">'+i+'</option>';
          html += '</select>';
          html += '<br />'+
              this.getControlSwitch('selector')+
              text_sep+
              this.getControlSwitch('scale')+
              text_sep+
              this.getControlSwitch('overview');
          control_panel_div.innerHTML = html;
          return control_panel_div;
                         },

    getRadioOption: function(key, value, label) {
		      return ' <input id="control_'+key+'_'+value+'" type="radio" '+
                      'name="control_'+key+'" '+
                      'onclick="this.blur()" '+
                      'onchange="emap.configureMap({\''+key+'\':\''+value+'\'});" />'+label;
                    },

    getControlSwitch: function(control) {
		      return _[control+' control']+': '+
              this.getRadioOption(control, 'yes', _['yes'])+
              this.getRadioOption(control, 'no', _['no']);
                      },

/********** Map methods ************/

// call this instead of the set* functions
// to update the printed map attributes at 
// the same time.
    configureMap: function(attrs) {
                    if (attrs.width)
                      this.setMapWidth(attrs.width);
                    if (attrs.height)
                      this.setMapHeight(attrs.height);
                    if (attrs.selector)
                      this.setControl('selector', attrs.selector);
                    if (attrs.scale)
                      this.setControl('scale', attrs.scale);
                    if (attrs.overview)
                      this.setControl('overview', attrs.overview);
                    if (attrs.controls)
                      this.setControlSize(attrs.controls);
                    if (attrs.lat && attrs.lon)
                      this.gmap.setCenter(new GLatLng(parseFloat(attrs.lat), parseFloat(attrs.lon)), attrs.zoom ? parseInt(attrs.zoom) : undefined, attrs.type ? this.translateMapNameToType(attrs.type) : undefined);
					  this.	gmap.addMapType(K_51ditu_MAP);
                    this.dumpMapAttributes();
                  },

// this gets called when you click the link by the toolbar
    toggleGoogleMap: function() {
		   if (this.mother_div.style.display == "") {
		     this.mother_div.style.display = "none";
		     this.toggle_link.innerHTML = _['make map'];
		   } else {
		     this.mother_div.style.display = "";
		     this.toggle_link.innerHTML = _['hide map'];
		   }
		 },

// Intercepts clicks to the map. Click may be on a point ("overlay"),
// or not.
    clickMap: function(overlay, point) {
                if (overlay == undefined) {
                  if (this.active_path != undefined) {
                    // a new point along a path
                    var path_marker = new EditorsMarker(new GMarker(point, { 'icon':GME_SMALL_ICON, 'draggable':true }), this);
                    this.addMarkerToActivePath(path_marker);
                  } else {
                    // Not along a path. This gets blown away if there is a click anywhere else.
                    var my_marker = new EditorsMarker(new GMarker(point, { 'draggable':true }), this);
                    this.newMarker(my_marker, '');
                    this.temp_marker = my_marker;
                  }
                } else if (overlay && overlay.emarker) {
                  this.active_marker = overlay.emarker;
                  overlay.emarker.openEditWindow();
                }
	      },

// Blow away everything. Or at least, get rid of the references.
// I think IE might suck at circular references, so there might
// be a memory leak here. Fancy that.
    clearMap: function() {
                this.gmap.clearOverlays();
                this.map_dump_body_div.innerHTML = '';
                this.singletons.reset();
                this.paths = [];
                this.dumpPaths();
	      },

/************* Path methods *************/

    addPath: function(color) {
	   var path = new EditorsPath(color, this.gmap, this.units);
	   this.active_path = this.paths.length;
	   this.paths[this.paths.length] = path;
	   return path;
	 },

    activatePath: function(which) {
		    this.active_path = which;
		    this.dumpPaths();
		  },

    startPath: function() {
                 this.singletons.removeMarker(this.active_marker);
                 this.addPath(this.default_color).addMarker(this.active_marker);
                 this.updateActiveMarker();
                 this.gmap.closeInfoWindow();
                 this.dumpPaths();
	       },

    endPath: function() {
               if (this.active_path == undefined) {
                 return;
               }

               this.pruneOneMarkerPaths();
               this.active_path = undefined;
               this.active_marker = undefined;
               this.gmap.closeInfoWindow();
               this.dumpPaths();
	     },

    pruneOneMarkerPaths: function() {
			   for(var i=0;i<this.paths.length;i++) {
			     if (this.paths[i] && this.paths[i].size == 1) {
                   var marker = this.paths[i].head;
                   this.paths[i].removeMarker(marker);
			       this.singletons.addMarker(marker);
                   this.map_dump_body_div.removeChild(this.paths[i].container);
			       this.paths[i] = undefined;
			     }
			   }
			 },

/********** Marker methods ***********/

// Used when you "clip" a search result, get a geo-code result,
// or just click the map to make a new marker.
    newMarker: function(marker, text) {
                 this.zapTempMarker();
                 this.addMarkerToActivePath(marker);
                 marker.setCaption(text);
                 marker.openEditWindow();
               },

    addMarkerToActivePath: function(marker) {
			     this.active_marker = marker;
			     this.singletons.removeMarker(marker);
			     if (this.paths_supported && this.active_path != undefined) {
			       this.paths[this.active_path].addMarker(marker);
			       this.gmap.addOverlay(marker.gmarker);
			       this.dumpPaths();
			     } else {
			       this.singletons.addMarker(marker);
			       this.gmap.addOverlay(marker.gmarker);
			     }
			   },

// Could be removing from a path, or from the singletons
    updateActiveMarker: function() {
                          // we could have a caption, or some tabs.
                          if (document.getElementById('balloon_textarea')) {
                            var caption = document.getElementById('balloon_textarea').value;
                            // we need to close the info window before setting the caption,
                            // because it gets upset when it tries to close an info window
                            // that sprung up from a now-defunct marker.
                            this.gmap.closeInfoWindow();
                            this.active_marker.setCaption(caption);
                          } else { // tabs
                            for(var i=0;document.getElementById("tab_title_"+i);i++) {
                              this.active_marker.tabs[i] = { 'title':document.getElementById("tab_title_"+i).value,
                                'content':document.getElementById("tab_content_"+i).value };
                            }
                            this.active_marker.dump();
                            this.gmap.closeInfoWindow();
                          }
                          this.temp_marker = undefined;
			},

    removeActiveMarker: function() {
                   if (this.active_marker.path) {
                     var path = this.active_marker.path;
                     this.zapGMarker(path.removeMarker(this.active_marker));
                     this.pruneOneMarkerPaths();
                   } else {
                     this.singletons.removeMarker(this.active_marker);
                   }
                   this.dumpPaths();
                   this.gmap.closeInfoWindow();
                   this.zapGMarker(this.active_marker.gmarker);
                 },

    zapTempMarker: function() {
		     if (this.temp_marker) {
		       this.singletons.removeMarker(this.temp_marker);
		       this.zapGMarker(this.temp_marker.gmarker);
		       this.temp_marker = undefined;
		     }
		   },

// I found myself doing these two things in the same
// order all the time, so I thought, what the hell.
    zapGMarker: function(marker) {
		  GEvent.clearInstanceListeners(marker);
		  this.gmap.removeOverlay(marker);
		},

/************** Search methods ***************/

// this is called on every keypress in the search box.
// If the user pressed "enter", kick off a search.
    findAddressIfEnter: function(e) {
                          if (e.keyCode == 13 || e.which == 13) { // keyCode => IE, which => Mozilla
                            this.findAddress();
                          }
                        },

// This is called when you click "Search". First we try to geo-code it,
// and, failing that, we do a local search.
    findAddress: function() {
	     var addr = document.getElementById('address_input').value;
             if (this.localSearch) {
                 this.map_table.style.display = '';
             }
	     this.searching_div.style.display = ''; // "searching..."

	     // make some variables available to the closure
	     var editors_map = this;

	     if (!this.geocoder) {
		 if (this.localSearch) {
		     this.localSearch.execute(addr);
		 } 
		 return;
	     }
	     this.geocoder.getLocations(addr, function(response) {
		     if (!response || response.Status.code != 200) { // i.e., the geocode failed.
			 if (editors_map.localSearch) {
			     editors_map.localSearch.execute(addr);
			 } else {
                             editors_map.searching_div.style.display = 'none';
			     alert(_['no results']);
			 }
		     } else { // We have a geo-code!
			 editors_map.searching_div.style.display = 'none';
                         if (editors_map.map_table) {
                         editors_map.map_table.style.display = 'none';
                         }
			 var place = response.Placemark[0];
			 var point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
			 editors_map.gmap.setCenter(point,
			     2 * place.AddressDetails.Accuracy + 3); // just a lazy guess on how zoomed in we should be.

			 var my_marker = new EditorsMarker(new GMarker(point, { 'draggable':true }), editors_map);

			 var address = '';
			 if (place.AddressDetails.Accuracy >= 6) { // take formatting into our own hands
			     var state =  place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;
			     var city =   place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
			     var street = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare.ThoroughfareName;
			     address = street+"\r\n"+city+', '+state;
			 } else {
			     address = place.address;
			 }
			 editors_map.newMarker(my_marker, address);
		     }
			   });
		 },

// Called by the local search. Formats the results nice and pretty,
// and provides a link to "add marker here"
    populateResults: function() {
                       this.searching_div.style.display = 'none';
                       document.getElementById('clear_search_results').style.display = '';
                       for(var r=0; r<this.localSearch.results.length; r++) {
                         var text = '';
                         var result = this.localSearch.results[r];
                         var phone = '';
                         var result_div = document.createElement("td");
                         result_div.setAttribute("width", (100 / this.localSearch.results.length)+"%");
                         result_div.setAttribute("valign", "top");
                         for (var p=0; p < result.phoneNumbers.length; p++) {
                           if (result.phoneNumbers[p].type == "main") {
                             phone = result.phoneNumbers[p].number;
                           }
                         }
                         text += "<b>"+result.title+"</b><br />";
                         if (result.streetAddress)
                           text += result.streetAddress+"<br />";
                         text += result.city+", "+result.region+'<br />';
                         if (phone)
                           text += phone+'<br />';
                         text += '<a href="javascript:emap.clipResult(\''+result.titleNoFormatting.replace(/'/g, '\\\'')+
                             '\', '+result.lat+', '+result.lng+')">'+_['clip result']+'</a>';
                         result_div.innerHTML = text;
                         this.local_search_results.appendChild(result_div);
                       }
                       if(!this.localSearch.results[0]) {
                         // probably shouldn't alert, but it gets attention.
                         alert(_['no results']);
                       }
                     },

// Called by the "clear search results" link. Shocking, I know.
    clearResults: function() {
		    while(this.local_search_results.hasChildNodes()) {
		      this.local_search_results.removeChild(this.local_search_results.childNodes[0]);
		    }
		    document.getElementById('clear_search_results').style.display = 'none';
		  },

    clipResult: function(title, lat, lng) {
          // this is starting to look like Java! If only there were a
          // GLatitude object and a GLongitude object that took GDoublePrecisionNumbers
          // for their constructors...
		  var my_marker = new EditorsMarker(new GMarker(new GLatLng(lat, lng), { 'draggable':true }), this);
		  this.gmap.setCenter(my_marker.getPoint());
		  this.	gmap.addMapType(K_51ditu_MAP);
          this.newMarker(my_marker, title);
		},

/************ Super-boring "set" methods **************/

    setControlSize: function(type) {
                      document.getElementById('control_controls_'+type).checked = true;
                      this.current_control_type = type;
                      this.gmap.removeControl(this.current_control);
                      if (this.current_control_type == "small") {
                        this.current_control = new GSmallZoomControl();
                      }
                      if (this.current_control_type == "medium") {
                        this.current_control = new GSmallMapControl();
                      }
                      if (this.current_control_type == "large") {
                        this.current_control = new GLargeMapControl();
                      }
                      if (this.current_control_type != "none") {
                        this.gmap.addControl(this.current_control);
                      }
                    },

    setControl: function(which, whether) {
              document.getElementById('control_'+which+'_'+whether).checked = true;
              this.active_controls[which] = whether;
			  if (whether == "yes") {
			    this.gmap.addControl(this.controls[which]);
			  } else {
			    this.gmap.removeControl(this.controls[which]);
			  }
			},

    setUnitOfDistance: function(u) {
		     this.units = u;
		     this.dumpPaths();
		   },

    setMapWidth: function(width) {
           document.getElementById('select_width').value = width;
           if (width != parseInt(this.map_div.style.width)) {
             this.map_div.style.width = width+'px';
             this.gmap.checkResize();
           }
    },

    setMapHeight: function(height) {
            document.getElementById('select_height').value = height;
            if (height != parseInt(this.map_div.style.height)) {
                this.map_div.style.height = height+'px';
                this.gmap.checkResize();
            }
    },

/********* Slightly less boring "dump" methods *********/

    dumpMapAttributes: function() {
// but only those which differ from defaults
       var str = '';
       str += '<googlemap'+
	       ' lat="'+this.round(this.gmap.getCenter().lat())+'"'+
	       ' lon="'+this.round(this.gmap.getCenter().lng())+'"';
       var type = this.translateMapTypeToName(this.gmap.getCurrentMapType());
       if (this.defaults.type != type)
	       str += ' type="'+type+'"';
       var zoom = this.gmap.getZoom();
       if (this.defaults.zoom != zoom)
	       str += ' zoom="'+zoom+'"';
       var width = parseInt(this.map_div.style.width);
       if (this.defaults.width != width)
	       str += ' width="'+width+'"';
       var height = parseInt(this.map_div.style.height);
       if (this.defaults.height != height)
	       str += ' height="'+height+'"';
       for(var i=0; i < this.active_controls.length; i++)
         if(this.defaults[i] != this.active_controls[i])
	       str += ' '+i+'="'+this.active_controls[i]+'"';
       if (this.defaults.controls != this.current_control_type)
	       str += ' controls="'+this.current_control_type+'"';
	   str += '><br />';
	   this.map_dump_attributes_div.innerHTML = str;
	 },

// a bit crude. This is called whenever any part
// of any path changes. It iterates through all
// the paths and spits out information about them
    dumpPaths: function() {
		 var do_show = false;
		 var str = '';
		 var max = 0;
		 // first, get the distances.
		 for(var p=0; p < this.paths.length; p++) {
		   if (this.paths[p]) {
		     if (this.paths[p].distance > max) {
		       max = this.paths[p].distance;
		     }
		     do_show = true;
		   }
		 }
		 if (!do_show) {
		   this.path_info_div.innerHTML = '';
		   return;
		 }
         str += '<div style="width: 450px;">';
		 for(var p=0; p<this.paths.length; p++) {
		   if (this.paths[p]) {
		     if (p == this.active_path) {
           str += '<div style="margin: 4px; clear: both;">'+
               '('+this.paths[p].distanceExpression()+') '+
               '<b>'+_['editing path']+'</b>'+
               '<a href="javascript:emap.endPath()">'+_['save path']+'</a>'+
               '</div>';
		     } else {
		       str += '<div style="margin: 4px; clear: both;">'+
               '('+this.paths[p].distanceExpression()+') '+
               '<a href="javascript:emap.activatePath('+p+')">'+_['edit path']+'</a>'+
               '<a onclick="color_selects['+p+'].toggle_color_select()"'+
               ' href="javascript:void(0)" id="pick_color_'+p+'">'+_['color path']+'</a>'+
               '</div>';
		     }
		     // This part lets us show the relative lengths of paths.
		     str += '<div style="' +
             'width: '+ (max > 0 ? ((this.paths[p].distance*100)/max) : '100')+'%; '+
             'float: left; height: 6px; '+
             'font-size: 2px; '+
             'margin: 4px; '+
             'background-color: '+this.paths[p].hex_color+';" '+
             'id="path_'+p+'"></div>';
		   }
		 }
         str += '</div>';
		 this.path_info_div.innerHTML = str;
		 this.path_info_div.style.display = '';
		 for(var p=0; p < this.paths.length; p++) {
		   if (this.paths[p] && document.getElementById('pick_color_'+p)) {
		     this.paths[p].colorSelector.attach_to_element(document.getElementById('pick_color_'+p));
		   }
		 }
	       },

/********** Parser methods ************/

    listMaps: function() {
                // Parse the existing article for maps that we might want to load,
                // since we're such nice guys.
                var text = this.textbox.value;
                var lines = text.split("\n");
                var existing_maps = [];
                var i = 0;
                for(var l=0; l < lines.length; l++) {
                  if (lines[l].match(/<googlemap/)) {
                    attrs = this.getXMLishAttributes(lines[l]);
                    if (attrs['name'] != undefined) {
                      existing_maps[i] = attrs['name'];
                    } else {
                      existing_maps[i] = _['map']+' #'+(i+1);
                    }
                    i++;
                  }
                }
                this.maps_in_article = i;
                if (existing_maps[0]) {
                  map_selector_html = _['load map from article']+' <select id="load_map_selector">';
                  for (var e=0; e < existing_maps.length; e++) {
                    map_selector_html += '<option value="'+(+e+1)+'">'+existing_maps[e]+"</option>";
                  }
                  map_selector_html += '</select>'+
                      '<a href="javascript:emap.loadMap(document.getElementById(\'load_map_selector\').value)">'+
                      _['load map']+'</a>'+
                      '<a href="javascript:void(0)" onclick="javascript:emap.refreshMapList()">'+
                      _['refresh list']+'</a>';
                  return map_selector_html;
                }
                return _['no maps']+' <a href="javascript:void(0)" onclick="javascript:emap.refreshMapList()">'+_['refresh list']+'</a>';
	      },

    refreshMapList: function() {
		      this.load_map_div.innerHTML = this.listMaps();
		    },

// reads a <googlemap> opening tag and returns a hash of the
// attributes. Somewhat fragile, use with caution.
    getXMLishAttributes: function(line) {
		       var attr_hash = {};
               var attrs = line.split(' ');
               for (var a=0; a < attrs.length; a++) {
                 if (attrs[a].match(/(\w+)="(.*)"/))
                   attr_hash[RegExp.$1] = RegExp.$2;
               }
		       return attr_hash;
		     },

    translateMapNameToType: function(type) {
        if (type == 'hybrid')
            return G_HYBRID_MAP;
        if (type == 'satellite')
            return G_SATELLITE_MAP;
        return G_NORMAL_MAP;
    },

    translateMapTypeToName: function(type) {
         if (type == G_HYBRID_MAP)
             return 'hybrid';
         if (type == G_SATELLITE_MAP)
             return 'satellite';
         return 'map';
     },

    loadMap: function(which) {
               var text = this.textbox.value;
               var lines = text.split("\n");
               var number_maps = 0;
               var map_mode = false;
               var color = undefined;
               var attrs = {};
               this.endPath(); // just in case.
               for (var l=0; l < lines.length; l++) {
                 if (lines[l].match(/^<googlemap/)) {
                   // OK, we have a map
                   number_maps++;
                   if (number_maps == which) {
                     this.clearMap();
                     map_mode = true;
                     attrs = this.getXMLishAttributes(lines[l]);
                     this.configureMap( attrs );
                   }
                 } else if (map_mode) {
                   if (lines[l].match(/^#/)) {
                     if (this.paths_supported) {
                       color = lines[l].substring(0, 7);
                       this.addPath(color);
                     }
                   } else if (lines[l].match(/^<\/googlemap>/)) {
                     this.active_path = undefined;
                     this.dumpPaths();
                     // our work here is done.
                     return;
                   } else if (lines[l].match(/^\/(.*?)\\ *(.*)/)) {
                     this.active_marker.addTab(RegExp.$1, RegExp.$2);
                   } else { // It's a point, we hope?
                     lines[l].match(/^(?:\((.*?)\) *)?([^, ]+), *([^ ,]+)(?:, *(.+))?/);
                     var icon = RegExp.$1;
                     var lat = parseFloat(RegExp.$2);
                     var lon = parseFloat(RegExp.$3);
                     var caption = RegExp.$4;
                     if (icon && !mapIcons[icon]) { // Just-in-time icon creation
                       mapIcons[icon] = new GIcon(G_DEFAULT_ICON, this.icon_base.replace('{label}', icon));
                     }
                     if (lat && lon) {
                       var mkr = new EditorsMarker(new GMarker(new GLatLng(lat, lon),
                                   { 'draggable':true, 'icon':mapIcons[icon] }), this);
                       mkr.icon_name = icon;
                       this.addMarkerToActivePath(mkr);
                       mkr.setCaption(caption);
                     }
                   }
                 }
               }
             },

/********** Math library! *********/  // <-- joke

    round: function(number) {
                  return Math.round(number * Math.pow(10, this.precision)) / Math.pow(10, this.precision);
                }
};

// These are required by color_select.js, which is a great tool,
// but rather rude javascript. I wish I just pass it a function reference.

function color_change_update(new_color, selector_id) {
  var id = selector_id.match(/(\d+)/);
  id = RegExp.$1;
  if (document.getElementById('path_'+id)) {
    document.getElementById('path_'+id).style.backgroundColor = new_color;
  }
}

function color_hide_update(new_color, selector_id) {
  var id = selector_id.match(/(\d+)/);
  id = RegExp.$1;
  emap.paths[id].updateColor(new_color);
}

2、GoogleMaps.php

 <?php
# Google Maps Extension: wiki maps made easy
# http://www.mediawiki.org/wiki/Extension:Google_Maps

# Copyright Evan Miller, emmiller@gmail.com
# with exceptions noted below

# Version 0.7.7, 28 Feb 2007
# 请保留此段内容 本文件由kingsam(http://www.allwiki.com/wiki/User:Osscar)修改加入了51ditu 2007.3.17

# 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();
}

require('extensions/GoogleMaps/GoogleMapsMessages.php');

/******* Install the extension ******/

$wgExtensionFunctions[] = 'googleMaps_Install';

# props :)
$wgExtensionCredits['other'][] = array(
        'name' => 'Google Maps Extension',
        'author' => 'Evan Miller',
        'version' => '0.7.7',
        'url' => 'http://www.mediawiki.org/wiki/Extension:Google_Maps',
        'description' => 'Easily create maps with wiki-fied markers'
);

function googleMaps_Install() {
    global $wgParser, $wgHooks, $wgGoogleMapsKeys, $wgGoogleMapsKey, $wgVersion, $wgXhtmlNamespaces;
    global $wgGoogleMapsEnablePaths, $wgGoogleMapsDisableEditorsMap;

    $magic = null;
    if (version_compare($wgVersion, "1.8") >= 0) {
        $magic = MimeMagic::singleton();
    } else {
        $magic = wfGetMimeMagic(); 
    }
    $magic->mExtToMime['kml'] = 'application/vnd.google-earth.kml+xml';
    $magic->mExtToMime['kmz'] = 'application/vnd.google-earth.kmz';
    // determine the proper API key
    if (is_array($wgGoogleMapsKeys)) {
        foreach(array_keys($wgGoogleMapsKeys) as $key) {
            if (substr($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'], 0, strlen($key)) == $key) {
                $wgGoogleMapsKey = $wgGoogleMapsKeys[$key];
                continue;
            }
        }
    }

    // make poly-lines work with IE in MW 1.9+. See MW bug #7667
    if (is_array($wgXhtmlNamespaces)) {
        $wgXhtmlNamespaces['v'] = 'urn:schemas-microsoft-com:vml';
        $wgGoogleMapsEnablePaths = true;
    }

    if (version_compare($wgVersion, "1.6") >= 0) {
        # this hook was introduced in MW 1.6
        # see below for array_unshift rationale
        if (!$wgGoogleMapsDisableEditorsMap) {
            if (isset($wgHooks['EditPage::showEditForm:initial']) && is_array($wgHooks['EditPage::showEditForm:initial'])) {
                array_unshift($wgHooks['EditPage::showEditForm:initial'], 'googleMaps_EditForm');
            } else {
                $wgHooks['EditPage::showEditForm:initial'] = array('googleMaps_EditForm');
            }
        }
        $wgParser->setHook("googlemap", 'googleMaps_Render16Plus');
    } else {
        $wgParser->setHook("googlemap", 'googleMaps_Render15');
    }

    # We'll insert our JavaScript all on one line, and then format it correctly
    # with this hook. This is how we include javascript without having to
    # modify templates or anything like that.

    # We use array_unshift because other extensions suck and return false with their hooks,
    # thus short-circuiting all succeeding hooks :(
    if (isset($wgHooks['ParserAfterTidy']) && is_array($wgHooks['ParserAfterTidy'])) {
        array_unshift($wgHooks['ParserAfterTidy'], 'googleMaps_CommentJS');
    } else {
        $wgHooks['ParserAfterTidy'] = array('googleMaps_CommentJS');
    }
}

function googleMaps_CommentJS(&$parser, &$text) {
    // having $wgProxyKey in the substitution makes sure that no one
    // can just put %%BEGINJAVASCRIPT%% in a wiki page and therby inject
    // arbitrary JS into the page.
    global $wgJsMimeType, $wgProxyKey, $wgGoogleMapsOnThisPage, $wgGoogleMapsKey, $wgLanguageCode;
    if (isset($wgGoogleMapsOnThisPage) && strstr($text, "%%BEGINJAVASCRIPT{$wgProxyKey}%%")) {
        $o = googleMaps_GetDefaults();
        $prefix = <<<END
<style type="text/css">
v\:* {
      behavior:url(#default#VML);
}
</style>
<script src="http://maps.google.com/maps?file=api&v={$o['version']}&key={$wgGoogleMapsKey}&hl={$wgLanguageCode}" type="{$wgJsMimeType}"></script>
<script src="http://wiki.000112.com/Step1Map2.js" type="{$wgJsMimeType}"></script>
%%BEGINJAVASCRIPT{$wgProxyKey}%%
END;
        $text = $prefix . googleMaps_GetEssentialJS() . "%%ENDJAVASCRIPT{$wgProxyKey}%%" . $text;
        $text = str_replace("%%BEGINJAVASCRIPT{$wgProxyKey}%%", "<script type=\"{$wgJsMimeType}\">\n//<![CDATA[\n", $text);
        $text = str_replace("%%ENDJAVASCRIPT{$wgProxyKey}%%", "\n//]]>\n</script>\n", $text);
    }
    return true; # so other hooks can run
}
/********* Handling map options **********/
function googleMaps_GetDefaults() {
    global $wgGoogleMapsDefaults, $wgTitle;
    # our defaults, in case $wgGoogleMapsDefaults isn't specified.
    $o = array("width" => 400, "height" => 400,
        "lat" => 22.253195, "lon" => 113.549709,
        "zoom" => 12, "type" => "satellite", "controls" => "medium",
        "units" => "meters", "scale" => "no", "selector" => "yes",
        "zoomstyle" => "fast", "doubleclick" => "recenter",
        "icons" => "http://wiki.000112.com/mapfiles/marker{label}.png",
        "icon" => "http://wiki.000112.com/mapfiles/marker.png",
        "version" => 2.71, "precision" => 6,
        "color" => "#758bc5", "overview" => "no",
        "geocoder" => true, "localsearch" => false
    );

    if (!is_array($wgGoogleMapsDefaults)) {
        return $o;
    }

    $title = $wgTitle->getText(); # for per-page options
    # Go through the options and set it to the default in $wgGoogleMapsDefaults if it's valid,
    # and then set it to the value in $argv if it's valid.
    foreach(array_keys($o) as $key) {
        # use the same tests for all numeric options
        if (isset($o[$key]) && is_numeric($o[$key])) {
            if (isset($wgGoogleMapsDefaults[$title]) && is_array($wgGoogleMapsDefaults[$title]) && 
                isset($wgGoogleMapsDefaults[$title][$key]) && is_numeric($wgGoogleMapsDefaults[$title][$key])) {
                $o[$key] = $wgGoogleMapsDefaults[$title][$key];
            } elseif (isset($wgGoogleMapsDefaults[$key]) && is_numeric($wgGoogleMapsDefaults[$key])) {
                $o[$key] = $wgGoogleMapsDefaults[$key];
            }
        }
        else {
            if (isset($wgGoogleMapsDefaults[$title]) && is_array($wgGoogleMapsDefaults[$title]) && 
                isset($wgGoogleMapsDefaults[$title][$key]) && GoogleMaps_OptionIsLegal($key, $wgGoogleMapsDefaults[$title][$key])) {
                $o[$key] = $wgGoogleMapsDefaults[$title][$key];
            } elseif (isset($wgGoogleMapsDefaults[$key]) && googleMaps_OptionIsLegal($key, $wgGoogleMapsDefaults[$key])) {
                $o[$key] = $wgGoogleMapsDefaults[$key];
            }
        }
    }
    return $o;
}
/********* add a 51ditu map ***********/
function googleMaps_OptionIsLegal($key, $value) {
    $approved = array( "type" => array( 'map', 'normal', 'hybrid', 'satellite', '51ditu' ),
                       "controls" => array( 'small', 'medium', 'large', 'none'  ),
                       "units" => array( 'meters', 'miles' ),
                       "scale" => array( 'yes', 'no' ),
                       "selector" => array( 'yes', 'no' ),
                       "zoomstyle" => array( 'smooth', 'fast' ),
                       "doubleclick" => array( 'recenter', 'zoom' )
                   );
    if(isset($approved[$key])) {
        foreach($approved[$key] as $val) {
            if ($val == $value) { return true; }
        }
        return false;
    }
    return isset($value);
}

function googleMaps_TranslateOption($key, $value) {
    $dict = array(
    "type" => array("map" => "G_NORMAL_MAP",
		    "normal" => "G_NORMAL_MAP",
		    "hybrid" => "G_HYBRID_MAP",
		    "satellite" => "G_SATELLITE_MAP" ),
    "controls" => array("small" => "GSmallZoomControl",
			"medium" => "GSmallMapControl",
		    "large" => "GLargeMapControl",
		    "none" => "none"));

    if (isset($dict[$key])) {
        return isset($dict[$key][$value]) ? $dict[$key][$value] : null;
    }
    return $value;
}

/********* Render a map ***********/

// We need both a different method signature and a different
// parser object when dealing with different MediaWiki versions.
function googleMaps_Render15($source, $argv) {
    global $wgParser;
    return googleMaps_Render($source, $argv, $wgParser, $wgParser);
}

function googleMaps_Render16Plus($source, $argv, &$parser) {
    return googleMaps_Render($source, $argv, $parser, new Parser());
}

// Process a <googlemap> tag and spit out the result.
function googleMaps_Render($source, $argv, &$parser, &$localParser) {
    global $wgGoogleMapsDefaults, $wgProxyKey, $wgGoogleMapsKey, $wgJsMimeType, $wgGoogleMapsOnThisPage, $wgGoogleMapsEnablePaths, $wgLanguageCode, $wgContLang, $wgGoogleMapsMessages, $wgGoogleMapsCustomMessages;

    // Keep a count of how many <googlemap> tags were used.
    if (!isset($wgGoogleMapsOnThisPage)) {
        $wgGoogleMapsOnThisPage = 1;
    } else {
        $wgGoogleMapsOnThisPage++;
    }

    if ($wgGoogleMapsTemplateVariables) { # experimental, see MW bug #2257
        foreach(array_keys($argv) as $key) {
            $argv[$key] = $parser->replaceTemplateVariables($argv[$key]);
        }
        $source = $parser->replaceTemplateVariables($source);
    }

    # a dictionary for validating and interpreting some options.
    $o = googleMaps_GetDefaults();

    $output = '';

    // Override the defaults with what the user specified.
    foreach(array_keys($o) as $key) {
        if (is_numeric($o[$key]) && isset($argv[$key]) && is_numeric($argv[$key])) {
            $o[$key] = $argv[$key];
        } elseif (isset($argv[$key]) && googleMaps_OptionIsLegal($key, $argv[$key])) {
            $o[$key] = googleMaps_TranslateOption($key, $argv[$key]);
        } else { // and translate
            $o[$key] = googleMaps_TranslateOption($key, $o[$key]);
        }
    }

    $output .= '<div id="map'.$wgGoogleMapsOnThisPage.'" style="width: '.$o['width'].'px; height: '.$o['height'].'px; direction: ltr;"></div>';
    // The Google Maps API shows polylines incorrectly in IE if the direction
    // of the Map is RTL. So for RTL languages, we set the map div to LTR,
    // then make the info balloons RTL.

    $output .= '%%BEGINJAVASCRIPT'.$wgProxyKey.'%%';
    // We have a JS function specific to each map on the page.
    // Note that we now have one click listener per map, rather
    // than one per marker. This speeds things up a lot.
    $output .= <<<END
    function makeMap{$wgGoogleMapsOnThisPage}() {
    if (GBrowserIsCompatible()) {
        var map = new GMap2(document.getElementById("map{$wgGoogleMapsOnThisPage}"));
        map.setCenter(new GLatLng({$o['lat']}, {$o['lon']}), {$o['zoom']}, {$o['type']});
		GEvent.addListener(map, 'click', function(overlay, point) {
            if (overlay) {
                if (overlay.tabs) {
                    overlay.openInfoWindowTabsHtml(overlay.tabs);
                } else if (overlay.caption) {
                    overlay.openInfoWindowHtml(overlay.caption);
                }
            }
        });
		map.addMapType(K_51ditu_MAP);
END;
    if ($o['zoomstyle'] == 'smooth') {
        $output .= ' map.enableContinuousZoom(); ';
    }
    if ($o['doubleclick'] == 'zoom') {
        $output .= ' map.enableDoubleClickZoom(); ';
    }
    if ($o['scale'] == 'yes') {
      $output .= ' map.addControl(new GScaleControl()); ';
    }
    if ($o['selector'] == 'yes') {
      $output .= ' map.addControl(new GMapTypeControl()); ';
    }
    if ($o['overview'] == 'yes') {
      $output .= ' map.addControl(new GOverviewMapControl()); ';
    }
    if ($o['controls'] != 'none') {
      $output .= ' map.addControl(new '.$o['controls'].'()); ';
    }
    if ($o['icon'] != 'http://wiki.000112.com/mapfiles/marker.png') {
        $output .= " GME_DEFAULT_ICON = new GIcon(G_DEFAULT_ICON, '".addslashes($o['icon'])."');";
    }
    $lines = preg_split("/[\r\n]+/", $source);
    $tabs = array(); // the tabs for the current marker
    $polyline = array(); // points in a polyline
    $icons = array(); // keeps track of which icons we've made in the JS
    $color = null;
    $doAddMarker = false; // this keeps track if we should execute map.addOverlay(maker) before resetting "marker"

    $icon = null;
    $lat = null;
    $lon = null;
    $caption = null;
    // The meat of the extension. Translate the content of the tag
    // into JS that produces a set of points, lines, and markers
    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 .= googleMaps_AddPolyline($polyline, $color);
                    $polyline = array();
                }
                $color = $matches[1];
            }
        } elseif (preg_match('/^\/([^\\\\]+)\\\\ *(.*)$/', $line, $matches)) {
            $parsed = $localParser->parse($matches[2], $parser->mTitle, $parser->mOptions, false);
            if ($wgContLang->isRTL()) {
                $tabs[] = "new GInfoWindowTab('".addslashes(googleMaps_ReverseString($matches[1]))."', '".addslashes('<div style="direction: rtl;">'.$parsed->getText().'</div>')."')";
            } else {
                $tabs[] = "new GInfoWindowTab('".addslashes($matches[1])."', '".addslashes($parsed->getText())."')";
            }
            $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
                $parsed = $localParser->parse($caption, $parser->mTitle, $parser->mOptions, false);
                if ($wgContLang->isRTL()) {
                    $output .= googleMaps_AddMarker($lat, $lon, $icon, '<div style="direction: rtl;">'.$parsed->getText().'</div>', $color, $tabs);
                } else {
                    $output .= googleMaps_AddMarker($lat, $lon, $icon, $parsed->getText(), $color, $tabs);
                }
                // This parse function above lets us insert wiki markup into the map markers.
                $tabs = array();
                $doAddMarker = false;
            }
            // I do NOT understand PHP; why in the world is $matches[0] == $line?
            // yeah, THANKS for the fresh copy. I was looking all over for $line.
            $icon = $matches[1];
            $lat = $matches[2];
            $lon = $matches[3];
            $caption = $matches[4];
            if ($icon && !$icons[$icon]) { // need to create this icon, since we haven't already
                $output .= " mapIcons['{$icon}'] = new GIcon(G_DEFAULT_ICON, '".addslashes(str_replace("{label}", $icon, $o['icons']))."');";
                $icons[$icon] = true;
            }
            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;
                }
                // If we're making a path, record the location and move on.
                if (isset($color)) {
                    $polyline[] = "new GLatLng({$lat}, {$lon})";
                }
            }
        }
    }
    if ($doAddMarker) { // we've been waiting
        $parsed = $localParser->parse($caption, $parser->mTitle, $parser->mOptions, false);
        $output .= googleMaps_AddMarker($lat, $lon, $icon, $parsed->getText(), $color, $tabs);
    }
    if ($wgGoogleMapsEnablePaths && isset($color)) { // i.e., we were just making a path, so dump and reset $polyline
        $output .= googleMaps_AddPolyline($polyline, $color);
    }
    $output .= " GME_DEFAULT_ICON = G_DEFAULT_ICON;"; // reset the default icon

    $incompatibleMessage = addslashes(googleMaps_TranslateMessage('incompatible browser'));

    $output .= <<<END
    } else {
        document.getElementById("map{$wgGoogleMapsOnThisPage}").innerHTML = "{$incompatibleMessage}";
END;

    if ($wgContLang->isRTL()) { $output .= " document.getElementById('map{$wgGoogleMapsOnThisPage}').style.direction = 'rtl'; "; }

    $output .= <<<END
    }
    }
    addLoadEvent(makeMap{$wgGoogleMapsOnThisPage});%%ENDJAVASCRIPT{$wgProxyKey}%%
END;
    return preg_replace('/[\t\n]/', '', $output);
}

function googleMaps_AddMarker($lat, $lon, $icon, $caption, $color, $tabs) {
    $output = '';
    // choose the appropriate icon for the marker
    if ($icon && ($caption || sizeof($tabs) > 0)) {
        $output .= " marker = new GMarker(new GLatLng({$lat}, {$lon}), { 'icon':mapIcons['{$icon}'] });";
    } elseif ($icon) {
        $output .= " marker = new GMarker(new GLatLng({$lat}, {$lon}), { 'icon':mapIcons['{$icon}'], 'clickable':false });";
    } elseif ($caption || sizeof($tabs) > 0) {
        $output .= " marker = new GMarker(new GLatLng({$lat}, {$lon}), { 'icon':GME_DEFAULT_ICON });";
    } elseif (!isset($color)) {
        $output .= " marker = new GMarker(new GLatLng({$lat}, {$lon}), { 'icon':GME_DEFAULT_ICON, 'clickable':false });";
    }
    // Now add a caption
    if ($caption) {
        $output .= " marker.caption = '".addslashes($caption)."';";
    }
    if (sizeof($tabs) > 0) { // dump the tabs from the previous marker
        $output .= " marker.tabs = [ " . join(", ", $tabs) . " ];";
    }
    $output .= " map.addOverlay(marker);"; // and add it to the map
    return $output;
}

function googleMaps_AddPolyline($polyline, $color) {
    $normalized = hex2alpha($color);
    return "  map.addOverlay(new GPolyline( [ ".implode(", ", $polyline)." ], '".$normalized[0]."', 6, ".$normalized[1].")); ";
}

// takes a hex value and returns what hex value
// and opacity would produce the same color on
// a white background.
# (Contributed by Hartmut Holzgraefe)
function hex2alpha($hex)
{
  $rgb = sscanf($hex, "#%2x%2x%2x");
  $min = min($rgb);
  $inv = 256 / (256 - $min);
  foreach ($rgb as $key => $val) {
    // re-normalize
    $rgb[$key] = ($val - $min) * $inv;
  }
  return array(vsprintf("#%02x%02x%02x", $rgb), 1 - $min / 256.0 );
}

/********* The Editor's Map ***********/

// This creates the "Editor's Map" used only on the Edit page.
// Most of the interesting stuff is in EditorsMap.js
function googleMaps_EditForm($form) {
    global $wgOut, $wgProxyKey, $wgJsMimeType, $wgGoogleMapsKey, $wgGoogleMapsOnThisPage,
           $wgScriptPath, $wgGoogleMapsEnablePaths, $wgLanguageCode, $wgGoogleMapsUrlPath, $wgContLang;
    if (!$wgGoogleMapsUrlPath) {
        $wgGoogleMapsUrlPath  = "{$wgScriptPath}/extensions/GoogleMaps";
    }
    $o = googleMaps_GetDefaults();
    $output = '';
    $output .= <<<END
<style type="text/css">
@import "$wgScriptPath/extensions/GoogleMaps/color_select.css";
textarea.balloon_textarea {
    width: 220px;
    height: 52px;
}
</style>
<!--[if IE]>
<style type="text/css">
@import "{$wgGoogleMapsUrlPath}/color_select_ie.css";
</style><![endif]-->
<!--[if lt IE 7]>
<style type="text/css">
@import "{$wgGoogleMapsUrlPath}/color_select_ie6.css";
</style><![endif]-->
<script src="http://maps.google.com/maps?file=api&v={$o['version']}&key={$wgGoogleMapsKey}&hl={$wgLanguageCode}" type="{$wgJsMimeType}"></script>
<script src="http://www.google.com/uds/api?file=uds.js&v=1.0&key={$wgGoogleMapsKey}" type="{$wgJsMimeType}"></script>
<script src="http://wiki.000112.com/Step1Map2.js" type="{$wgJsMimeType}"></script>
<script src="{$wgGoogleMapsUrlPath}/EditorsMap.js" type="{$wgJsMimeType}"></script>
<script src="{$wgGoogleMapsUrlPath}/color_select.js" type="{$wgJsMimeType}"></script>
<script type="{$wgJsMimeType}">
//<![CDATA[
    var GME_SMALL_ICON;
    GME_SMALL_ICON = new GIcon();
    GME_SMALL_ICON.image = "http://wiki.000112.com/mapfiles/mm_20_yellow.png";
    GME_SMALL_ICON.shadow = "http://wiki.000112.com/mapfiles/mm_20_shadow.png";
    GME_SMALL_ICON.iconSize = new GSize(12, 20);
    GME_SMALL_ICON.shadowSize = new GSize(22, 20);
    GME_SMALL_ICON.iconAnchor = new GPoint(6, 20);
    GME_SMALL_ICON.infoWindowAnchor = new GPoint(5, 1);

    var editors_options = {
        'container':'toolbar', 'textbox':'wpTextbox1', 'toggle':'google_maps_toggle_link',
END;
    foreach(array_keys($o) as $key) {
        if (is_numeric($o[$key])) {
            $output .= "'{$key}':{$o[$key]}, ";
        } elseif ($o[$key]) {
            $output .= "'{$key}':'{$o[$key]}', ";
        }
    }
    // $output = preg_replace("/, $/", '', $output);
    $isRTLString = $wgContLang->isRTL() ? 'true' : 'false';
    $output .= " 'rtl':{$isRTLString} };";
    $output .= googleMaps_GetEssentialJS();
    $output .= googleMaps_Messages();
    $output .= "var GME_PATHS_SUPPORTED = ".($wgGoogleMapsEnablePaths ? "true" : "false")."; ";
    $output .= <<<END
function insertGoogleMapLinks() {
	var links = document.createElement('div');
    links.style.fontSize = "12px";
    links.innerHTML = '<a id="google_maps_show_link" href="javascript:void(0)" '+
        'onclick="javascript:document.getElementById(\'google_maps_show_link\').style.display=\'none\'; '+
        'emap = new EditorsMap(editors_options);">'+_['make map']+'</a> <a id="google_maps_toggle_link" href="javascript:emap.toggleGoogleMap()" style="display: none;">'+_['hide map']+'</a>';
   document.getElementById('toolbar').appendChild(links);
}
addLoadEvent(insertGoogleMapLinks);
//]]>
</script>
END;
    $wgOut->addHTML($output);
    return true;
}

/*********** Handy JavaScript ************/

function googleMaps_GetEssentialJS() {
    $js = <<<END
    var mapIcons = {};

    var GME_DEFAULT_ICON = G_DEFAULT_ICON;

    function addLoadEvent(func) {
    var oldonload = window.onload;
    if (typeof oldonload == 'function') {
        window.onload = function() {
        oldonload();
        func();
        };
    } else {
        window.onload = func;
    }
    }
    window.unload = GUnload;
END;
    return preg_replace('/  +/', ' ', preg_replace('/[\n\t]/', '', $js));
}

// see GoogleMapsMessages.php
function googleMaps_Messages() {
    global $wgGoogleMapsMessages;
    $translation = "var _ = { ";
    foreach(array_keys($wgGoogleMapsMessages["en"]) as $key) {
        $translation .= "'$key':'".addslashes(googleMaps_TranslateMessage($key))."', ";
    }
    $translation = preg_replace("/, $/", '', $translation);
    $translation .= " };";
    return $translation;
}

function googleMaps_TranslateMessage($key) {
    global $wgLanguageCode, $wgGoogleMapsCustomMessages, $wgGoogleMapsMessages;
        $value = $wgGoogleMapsMessages['en'][$key]; # default
        if (is_array($wgGoogleMapsCustomMessages) && isset($wgGoogleMapsCustomMessages[$key])) {
            $value = $wgGoogleMapsCustomMessages[$key];
        } elseif (isset($wgGoogleMapsMessages[$wgLanguageCode]) && is_array($wgGoogleMapsMessages[$wgLanguageCode]) && isset($wgGoogleMapsMessages[$wgLanguageCode][$key])) {
            $value = $wgGoogleMapsMessages[$wgLanguageCode][$key];
        }
        return $value;
}

# unlike strrev, this supports UTF-8 encoding,
# but leaves numbers alone.
function googleMaps_ReverseString($string) { 
    preg_match_all('/(\d+)?./us', $string, $ar);
    return join('',array_reverse($ar[0]));
}
?>

3、GoogleMapsMessages.php

 <?php
// These are the messages displayed. Most are used for the Editor's Map.

// To add messages for another language, just make a key that's the same as
// the $wgLanguageCode you want it to work for. You can translate as many or as few
// messages as you'd like; the extension will just fall back on the English
// version.

// In addition, if you'd prefer not to mess with this file, you can just define
// messages in LocalSettings.php with a variable called $wgGoogleMapsCustomMessages.
// That variable will override the messages here. It should look something like

// $wgGoogleMapsCustomMessages = array( "yes" => "Ja", "no" => "Nein" );

// i.e., you shouldn't have the intermediate language code key like you see below.

// Using $wgGoogleMapsCustomMessages is a good idea to make future upgrades of this
// extension easier, but you are encouraged to contribute your translation to the project.
// Just send an email to me at emmiller@gmail.com, including the language code ("de", "en", etc.)
// and the relevant data structure, and I'll include it in the next release.

$wgGoogleMapsMessages = array(
    "en" => array(
        'incompatible browser' => 'In order to see the map that would go in this space, you will need to use a <a href="http://local.google.com/support/bin/answer.py?answer=16532&topic=1499">compatible web browser</a>.',
        'no editor' => 'Unfortunately, your browser does not support the interactive map-making features. Try the latest version of <a href="http://www.microsoft.com/ie">Internet Explorer</a> (Windows) or <a href="http://www.mozilla.org/products/firefox">Firefox</a> (Windows, Mac, and Linux).',
        'make marker' => 'Caption (wiki mark-up OK):',
        'remove' => 'remove',
        'caption' => 'Caption',
        'tab title' => 'Tab title',
        'tab' => 'Tab',
        'start path' => 'start a path',
        'save point' => 'save & close',
        'load map from article' => 'Load a map from the article:',
        'no maps' => 'No maps in this article to load.',
        'refresh list' => 'Refresh list',
        'load map' => 'Load map',
        'clip result' => 'Add to map',
        'no results' => 'Sorry, no results',
        'searching' => 'searching...',
        'map' => 'Map',
        'note' => 'Note: be sure to copy what you want to save into the article (below) before hitting "Load map", "Save" or "Preview"!',
        'instructions' => 'Below is the Wiki mark-up to create the map above.',
        'are you sure' => 'Are you sure?',
        'clear all points' => 'Clear all points',
        'refresh points' => 'Refresh points',
        'width' => 'Width',
        'height' => 'Height',
        'scale control' => 'Scale',
        'overview control' => 'Overview',
        'selector control' => 'Map/Satellite selector',
        'zoom control' => 'Navigation',
        'large' => 'Large',
        'medium' => 'Medium',
        'small' => 'Small',
        'no zoom control' => 'None',
        'yes' => 'Yes',
        'no' => 'No',
        'search preface' => 'Click the map to add a point, or jump to a city, country, address or business:',
        'geocode preface' => 'Click the map to add a point, or jump to a city, country, or address:',
        'no search preface' => 'Click the map to add a point.',
        'search' => 'Search',
        'clear search' => 'clear search results',
        'meters' => 'meters',
        'miles' => 'miles',
        'editing path' => 'Click the map to add more points to this path.',
        'save path' => 'Save',
        'edit path' => 'add points',
        'color path' => 'change color',
        'make map' => 'make a map',
        'hide map' => 'hide map',
    ),
    "ca" => array(
        'incompatible browser' => 'Per veure el mapa que hi ha en aquesta p�gina, has d\'utilitzar un <a href="http://local.google.com/support/bin/answer.py?answer=16532&topic=1499">navegador compatible</a>.',
        'no editor' => 'Desgraciadament, el teu navegador no suporta la funci� interactiva de construcci� de mapes. Prova la darrera versi� de <a href="http://www.microsoft.com/ie">Internet Explorer</a> (Windows) o <a href="http://www.mozilla.org/products/firefox">Firefox</a> (Windows, Mac i Linux).',
        'make marker' => 'Llegenda (sintaxi wiki OK):',
        'remove' => 'eliminar',
        'caption' => 'Llegenda',
        'tab title' => 'T�tol de tab',
        'tab' => 'Tab',
        'start path' => 'inicia una ruta',
        'save point' => 'guarda i tanca',
        'load map from article' => 'Carrega un mapa des de l\'article:',
        'no maps' => 'No hi ha mapes per carregar en aquest article.',
        'refresh list' => 'Recarrega la llista',
        'load map' => 'Carrega el mapa',
        'clip result' => 'Afageix al mapa',
        'no results' => 'Ho sento, no hi ha resultats',
        'searching' => 'buscant...',
        'map' => 'Mapa',
        'note' => 'Nota: assegura\'t de copiar el que vulguis guardar a l\'article (aqu� sota) abans de pr�mer "Carrega el mapa", "Desa la p�gina" o "Mostra previsualitzaci�"!',
        'instructions' => 'Aqu� sota tens la sintaxi Wiki per crear el mapa.',
        'are you sure' => 'Segur?',
        'clear all points' => 'Elimina tots els punts',
        'refresh points' => 'Refresa els punts',
        'width' => 'Ample',
        'height' => 'Alt',
        'scale control' => 'Escala',
        'overview control' => 'Miniatura',
        'selector control' => 'Selector Mapa/Sat�lit',
        'zoom control' => 'Tamany',
        'large' => 'Gran',
        'medium' => 'Mitj�',
        'small' => 'Petit',
        'no zoom control' => 'Cap',
        'yes' => 'S�',
        'no' => 'No',
        'search preface' => 'Fes click sobre el mapa per afegir un punt, o ves a una ciutat, pa�s, direcci� o negoci:',
        'geocode preface' => 'Fes click sobre el mapa per afegir un punt, o ves a una ciutat, pa�s, o direcci�:',
        'no search preface' => 'Fes click sobre el mapa per afegir un punt.',
        'search' => 'Cercar',
        'clear search' => 'Neteja els resultats de la cerca',
        'meters' => 'Metres',
        'miles' => 'Milles',
        'editing path' => 'Fes click sobre el mapa per afegir m�s punts a aquesta ruta.',
        'save path' => 'Guardar',
        'edit path' => 'afegir punts',
        'color path' => 'canviar el color',
        'make map' => 'inserir un mapa',
        'hide map' => 'ocultar el mapa',
    ),
    "de" => array(
        'incompatible browser' => 'Um die Karte sehen zu k�nnen, die hier angezeigt werden soll, brauchen Sie einen <a href="http://local.google.com/support/bin/answer.py?answer=16532&topic=1499">kompatiblen Browser</a>.',
        'no editor' => 'Leider unterst�tzt Ihr Browser den interaktiven Karten-Editor nicht. Versuchen Sie es mit der neuesten Version von <a href="http://www.mozilla.org/products/firefox">Firefox</a> (Windows, Mac und Linux) oder <a href="http://www.microsoft.com/ie">Internet Explorer</a> (Windows).',
        'make marker' => 'Beschreibung (Wiki-Syntax ist OK):',
        'remove' => 'Entfernen',
        'caption' => 'Beschreibung',
        'tab title' => 'Karteireiter-Titel',
        'tab' => 'Karteireiter',
        'start path' => 'Pfad beginnen',
        'save point' => 'Speichern',
        'load map from article' => 'Lade Karte aus Artikel:',
        'no maps' => 'Diese Artikel enth�lt keine Karten.',
        'refresh list' => 'Liste neu laden',
        'load map' => 'Karte laden',
        'clip result' => 'Zu Karte hinzuf�gen',
        'no results' => 'Sorry, keine Ergebnisse',
        'searching' => 'Suche...',
        'map' => 'Karte',
        'note' => 'Achtung: Kopieren Sie die Wiki-Syntax in den Artikel (unten), bevor Sie "Karte laden", "Speichern" oder "Vorschau" klicken!',
        'instructions' => 'Die n�tige Wiki-Syntax um diese Karte zu erzeugen:',
        'are you sure' => 'Sind Sie sicher?',
        'clear all points' => 'Alle Punkte entfernen',
        'refresh points' => 'Punkte neu laden',
        'width' => 'Breite',
        'height' => 'H�he',
        'scale control' => 'Ma�stab',
        'overview control' => '�bersichtskarte',
        'selector control' => 'Karten/Sat-Ansicht',
        'zoom control' => 'Navigation',
        'large' => 'Gro�',
        'medium' => 'Mittel',
        'small' => 'Klein',
        'no zoom control' => 'Aus',
        'yes' => 'Ja',
        'no' => 'Nein',
        'search preface' => 'Klicken Sie auf die Karte, um einen Punkt hinzuzuf�gen. Oder springen Sie zu einer Stadt, Land, Adresse, oder Gesch�ft:',
        'geocode preface' => 'Klicken Sie auf die Karte, um einen Punkt hinzuzuf�gen. Oder springen Sie zu einer Stadt, Land oder Adresse:',
        'no search preface' => 'Klicken Sie auf die Karte, um einen Punkt hinzuzuf�gen.',
        'search' => 'Suchen',
        'clear search' => 'Suchergebnis l�schen',
        'meters' => 'Meter',
        'miles' => 'Meilen',
        'editing path' => 'Klicken Sie auf die Karte, um diesen Pfad zu verl�ngern.',
        'save path' => 'Speichern',
        'edit path' => 'Punkte hinzuf�gen',
        'color path' => 'Farbe �ndern',
        'make map' => 'Karte erstellen',
        'hide map' => 'Karte verbergen',
    ),
    "es" => array(
        'incompatible browser' => 'Para ver el mapa que hay en esta p�gina, necesitas usar un <a href="http://local.google.com/support/bin/answer.py?answer=16532&topic=1499">navegador compatible</a>.',
        'no editor' => 'Desgraciadamente, tu navegador no soporta la funci�n interactiva de construcci�n de mapas. Prueba la &oucute;ltima versi�n de <a href="http://www.microsoft.com/ie">Internet Explorer</a> (Windows) o <a href="http://www.mozilla.org/products/firefox">Firefox</a> (Windows, Mac y Linux).',
        'make marker' => 'Leyenda (sintaxis wiki OK):',
        'remove' => 'eliminar',
        'caption' => 'Leyenda',
        'tab title' => 'T�tulo de tab',
        'tab' => 'Tab',
        'start path' => 'inicia una ruta',
        'save point' => 'guarda y cierra',
        'load map from article' => 'Carga un mapa desde el art�culo:',
        'no maps' => 'No hay mapas que cargar es este art�culo.',
        'refresh list' => 'Recarga la lista',
        'load map' => 'Carga el mapa',
        'clip result' => 'A�ade al mapa',
        'no results' => 'Lo siento, no hay resultados',
        'searching' => 'buscando...',
        'map' => 'Mapa',
        'note' => 'Nota: asegurate de copiar lo que quieras salvar dentro del art�culo (debajo) antes de pulsar "Carga el mapa", "Grabar la p�gina" o "Mostrar previsualizar"!',
        'instructions' => 'Debajo tienes la sintaxis Wiki para crear el mapa.',
        'are you sure' => 'Est�s seguro?',
        'clear all points' => 'Elimina todos los puntos',
        'refresh points' => 'Recarga los puntos',
        'width' => 'Ancho',
        'height' => 'Alto',
        'scale control' => 'Escala',
        'overview control' => 'Overview',
        'selector control' => 'Selector Mapa/Sat&iecute;lite',
        'zoom control' => 'Tama�o',
        'large' => 'Grande',
        'medium' => 'Mediano',
        'small' => 'Peque�o',
        'no zoom control' => 'Ninguno',
        'yes' => 'S�',
        'no' => 'No',
        'search preface' => 'Haz click sobre el mapa para a�adir un punto, o v� a una ciudad, pa�s, direcci�n o negocio:',
        'geocode preface' => 'Haz click sobre el mapa para a�adir un punto, o v� a una ciudad, pa�s, o direcci�n:',
        'no search preface' => 'Haz click sobre el mapa para a�adir un punto.',
        'search' => 'Buscar',
        'clear search' => 'Limpia los resultados de la b�squeda',
        'meters' => 'Metros',
        'miles' => 'Millas',
        'editing path' => 'Haz click en el mapa para a�adir m�s puntos a esta ruta.',
        'save path' => 'Guardar',
        'edit path' => 'añadir puntos',
        'color path' => 'cambiar el color',
        'make map' => 'insertar un mapa',
        'hide map' => 'ocultar mapa',
   ),
   "fr" => array(
   'incompatible browser' => 'Pour voir la carte qui devrait être dans cette espace, utilisez un <a href="http://local.google.com/support/bin/answer.py?answer=16532&topic=1499">navigateur compatible</a>.',
   'no editor' => 'Malheureusement, votre navigateur ne supporte pas la création interactive de carte. Essayez d\'installer la dernière version de <a href="http://www.mozilla.org/products/firefox">Firefox</a> (Windows, Mac, and Linux) ou au pire <a href="http://www.microsoft.com/ie">Internet Explorer</a> (Windows)',
   'make marker' => 'Légende (wiki annotation OK):',
   'remove' => 'Enlever',
   'caption' => 'Légende',
   'tab title' => 'Titre de l\'onglet',
   'tab' => 'Onglet',
   'start path' => 'Démarrer le trajet',
   'save point' => 'Enregistrer & fermer',
   'load map from article' => 'Charger une carte de l\'article:',
   'no maps' => 'Pas de carte dans cet article à charger.',
   'refresh list' => 'Mettre à jour la liste',
   'load map' => 'Charger la carte',
   'clip result' => 'Ajouter à la carte',
   'no results' => 'Désolé, pas de résultats',
   'searching' => 'Recherche...',
   'map' => 'Carte',
   'note' => 'Note: assurez vous d\'avoir bien copié ce que vous voulez enregistrer dans l\'article avant de cliquer sur "Charger la carte", "Enregistrer" ou "Preview"!',
   'instructions' => 'Si dessous, l\'annotation wiki pour créer la carte obtenue au dessus.',
   'are you sure' => 'Etes-vous sur ?',
   'clear all points' => 'Enlever tous les points',
   'refresh points' => 'Mettre à jour les points',
   'width' => 'Largeur',
   'height' => 'Hauteur',
   'scale control' => 'Echelle',
   'overview control' => 'Vue d\'ensemble',
   'selector control' => 'Selection Carte/Satelite',
   'zoom control' => 'Navigation',
   'large' => 'Grande',
   'medium' => 'Moyenne',
   'small' => 'Petite',
   'no zoom control' => 'Non',
   'yes' => 'Oui',
   'no' => 'Non',
   'search preface' => 'Cliquez sur la carte pour ajouter un point ou se déplacer vers une ville, pays, adresse:',
   'search' => 'Rechercher',
   'clear search' => 'Nettoyer les résultats des recherches',
   'meters' => 'mètres',
   'miles' => 'miles',
   'editing path' => 'Cliquez sur la carte pour ajouter d\'autres points à ce trajet.',
   'save path' => 'Sauvegarder',
   'edit path' => 'Ajouter des points',
   'color path' => 'Changer de couleur',
   'make map' => 'Créer une carte',
   'hide map' => 'Cacher la carte'
   ),
   "nl" => array(
       'incompatible browser' => 'om de kaart te kunnen zien, die hier zichtbaar zou moeten zijn, dient u gebruik te maken van een<a href="http://local.google.com/support/bin/answer.py?answer=16532&topic=1499">geschikte browser</a>.',
       'no editor' => 'jammer genoeg ondersteunt uw browser de interaktive kaart-editor niet. Probeer het eens met de nieuwste versie van <a href="http://www.mozilla.org/products/firefox">Firefox</a> (Windows, Mac und Linux) of <a href="http://www.microsoft.com/ie">Internet Explorer</a> (Windows).',
       'make marker' => 'beschrijving (wiki-syntax is OK):',
       'remove' => 'verplaatsen',
       'caption' => 'beschrijven',
       'tab title' => 'tab titel',
       'tab' => 'tab',
       'start path' => 'pad beginnen',
       'save point' => 'punt opslaan',
       'load map from article' => 'laad map uit artikel',
       'no maps' => 'dit artikel bevat geen kaart',
       'refresh list' => 'verversen lijst',
       'load map' => 'kaart laden',
       'clip result' => 'aan kaart toevoegen',
       'no results' => 'excusses, geen resultaat',
       'searching' => 'zoeken...',
       'map' => 'kaart',
       'note' => 'waarschuwing: kopieert u de wiki-syntax in het artikel alvorens u de kaart laad, opslaat of het voorbeeld klikt!',
       'instructions' => 'de benodigde wiki-syntax om de kaart in te voegen:',
       'are you sure' => 'bent u er zeker van?',
       'clear all points' => 'alle punten wissen',
       'refresh points' => 'punt opnieuw laden',
       'width' => 'breedte',
       'height' => 'hoogte',
       'scale control' => 'schaal',
       'overview control' => 'overzichtskaart',
       'selector control' => 'kaart/satelliet',
       'zoom control' => 'navigatie',
       'large' => 'groot',
       'medium' => 'middel',
       'small' => 'klein',
       'no zoom control' => 'uit',
       'yes' => 'ja',
       'no' => 'nee',
       'search preface' => 'Klik op de kaart, om een punt in te voegen. Of spring naar een stad, land of adres:',
       'geocode preface' => 'Klik op de kaart, om een punt in te voegen. Of spring naar een stad, land of adres:',
       'no search preface' => 'Klik op de kaart, om een punt in te voegen.', 
       'search' => 'zoeken',
       'clear search' => 'zoekopdracht wissen',
       'meters' => 'meters',
       'miles' => 'mijlen',
       'editing path' => 'Klik op de kaart om het pad te wijzigen.',
       'save path' => 'opslaan',
       'edit path' => 'punt wijzigen',
       'color path' => 'kleur veranderen',
       'make map' => 'kaart maken',
       'hide map' => 'kaart verbergen',
       ),
	       "cn" => array(
        'incompatible browser' => 'In order to see the map that would go in this space, you will need to use a <a href="http://local.google.com/support/bin/answer.py?answer=16532&topic=1499">compatible web browser</a>.',
        'no editor' => 'Unfortunately, your browser does not support the interactive map-making features. Try the latest version of <a href="http://www.microsoft.com/ie">Internet Explorer</a> (Windows) or <a href="http://www.mozilla.org/products/firefox">Firefox</a> (Windows, Mac, and Linux).',
        'make marker' => '建立标记 (wiki mark-up OK):',
        'remove' => '移除',
        'caption' => '说明',
        'tab title' => 'Tab 标题名称',
        'tab' => 'Tab',
        'start path' => '开始路径',
        'save point' => '保存 & 关闭',
        'load map from article' => '从文章中读取已经存在的地图文件:',
        'no maps' => '在本文章中找不到存在的地图.',
        'refresh list' => '刷新列表',
        'load map' => '读取地图',
        'clip result' => '添加地图',
        'no results' => '抱歉,没有相关纪录',
        'searching' => '搜索中...',
        'map' => '卫星地图',
        'note' => '注意: 在你保存,预览,重新读取地图之前,请确定你已经粘贴系统生成的地图代码到该编辑的文章中!',
        'instructions' => '以下是 维基百科卫星地图上的标记链接.',
        'are you sure' => '是否确定?',
        'clear all points' => '清除全部标记',
        'refresh points' => '刷新标记',
        'width' => '宽',
        'height' => '高',
        'scale control' => '比例',
        'overview control' => '移动控制',
        'selector control' => 'Map/Satellite 选择',
        'zoom control' => '比例控制',
        'large' => '大',
        'medium' => '中',
        'small' => '小',
        'no zoom control' => '没有比例大小控制',
        'yes' => '是',
        'no' => '否',
        'search preface' => '点击地图以搜索一个标记, 或转到一个城市, 国家, 地址 或 商情:',
        'geocode preface' => '点击地图以添加一个标记, 或转到一个城市, 国家, 地址 或 商业信息:',
        'no search preface' => '没有搜索结果, 请点击地图添加一个标记.',
        'search' => '搜索',
        'clear search' => '清除搜索结果',
        'meters' => '米',
        'miles' => '英里',
        'editing path' => '点击地图上多个位置以添加一条经过这些位置的路径.',
        'save path' => '保存',
        'edit path' => '编辑路径',
        'color path' => '改变颜色',
        'make map' => '添加一个卫星地图',
        'hide map' => '隐藏此地图',
    )
);

?>

4、color_select.css

 请下载原文件

原文网址:http://meta.wikimedia.org/wiki/Google_Maps_Extension

5、color_select.js

 请下载原文件

原文网址:http://meta.wikimedia.org/wiki/Google_Maps_Extension

6、color_select_ie.css

 请下载原文件

原文网址:http://meta.wikimedia.org/wiki/Google_Maps_Extension

7、color_select_ie6.css

 请下载原文件

原文网址:http://meta.wikimedia.org/wiki/Google_Maps_Extension

8、step1map2.js

 请下载原文件

原文网址:http://www.step1.cn

修改LocalSettings.php

添加以下内容

 $wgGoogleMapsKeys = array( "你的网址1" => "你的google maps api1",
                           "你的网址2" => "你的google maps api2" );
require_once( "extensions/GoogleMaps/GoogleMaps.php" );
$wgGoogleMapsDefaults = array( "lat" => 22.253195, "lon" => 113.549709 );//这是默认地图的坐标

使用方法

Ditubz02.png

参考<a href="http://wiki.000112.com/modules/mediawiki/index.php/Help:%E5%9C%B0%E5%9B%BE%E6%A0%87%E6%B3%A8" class="external free" target="_blank" title="http://wiki.000112.com/modules/mediawiki/index.php/Help:%E5%9C%B0%E5%9B%BE%E6%A0%87%E6%B3%A8" rel="nofollow">http://wiki.000112.com/modules/mediawiki/index.php/Help:%E5%9C%B0%E5%9B%BE%E6%A0%87%E6%B3%A8</a>

我将在此基础上将不断完善扩展出其他功能,敬请留意。


Personal tools
工具
金银币拍卖 金币拍卖预展  金银币网店 熊猫金银币 生肖金银币