 function ArrowHandler() {
  this.setMap(map);
  // MapCanvasProjection is only available after draw has been called.
  //  this.draw = function() {};
  // Markers with 'head' arrows must be stored
  this.arrowheads = [];
 }

 ArrowHandler.prototype = new google.maps.OverlayView();

 // Draw is inter alia called on zoom change events.
 // So we can use the draw method as zoom change listener
 ArrowHandler.prototype.draw = function() {

  if (this.arrowheads.length > 0) {
   for (var i = 0, m; m = this.arrowheads[i]; i++) {
     m.setOptions({ position: this.usePixelOffset(m.p1, m.p2) });
   }
  }
 };


 // Computes the length of a polyline in pixels
 // to adjust the position of the 'head' arrow
 ArrowHandler.prototype.usePixelOffset = function(p1, p2) {

   var proj = this.getProjection();
   var g = google.maps;
   var dist = 12; // Half size of triangle icon

   var pix1 = proj.fromLatLngToContainerPixel(p1);
   var pix2 = proj.fromLatLngToContainerPixel(p2);
   var vector = new google.maps.Point(pix2.x - pix1.x, pix2.y - pix1.y);
   var length = Math.sqrt(vector.x * vector.x + vector.y * vector.y);
   var normal = new google.maps.Point(vector.x/length, vector.y/length);
   var offset = new google.maps.Point(pix2.x - dist * normal.x, pix2.y - dist * normal.y);

   return proj.fromContainerPixelToLatLng(offset);
 };


  // Returns the triangle icon object
 ArrowHandler.prototype.addIcon = function(file) {
   var icon = new google.maps.MarkerImage("http://www.cheboksary.ws/i/arrow/" + file,
    new google.maps.Size(24, 24), null, new google.maps.Point(12, 12));
   return icon;
  };

  // Creates markers with corresponding triangle icons
 ArrowHandler.prototype.create = function(p1, p2, mode) {
   var markerpos;
   if (mode == "onset") markerpos = p1;
   else if (mode == "head") markerpos = this.usePixelOffset(p1, p2);
   else if (mode == "midline") markerpos = google.maps.geometry.spherical.interpolate(p1, p2, .5);

   // Compute the bearing of the line in degrees
   var dir = google.maps.geometry.spherical.computeHeading(p1, p2).toFixed(1);
    // round it to a multiple of 3 and correct unusable numbers
    dir = Math.round(dir/3) * 3;
    if (dir < 0) dir += 240;
    if (dir > 117) dir -= 120;
    // use the corresponding icon
    var icon = this.addIcon("dir_" +dir+ ".png");
    var marker = new google.maps.Marker({position: markerpos,
     map: map, icon: icon, clickable: false
    });
    if (mode == "head") {
     // Store markers with 'head' arrows to adjust their offset position on zoom change
     marker.p1 = p1;
     marker.p2 = p2;
     this.arrowheads.push(marker);
    }
  };

 ArrowHandler.prototype.load = function (points, mode) {
    for (var i = 0; i < points.length-1; i++) {
      var p1 = points[i],
      p2 = points[i + 1];
      this.create(p1, p2, mode); 
    }
 };

var iconShadow  = new google.maps.MarkerImage('http://www.google.com/mapfiles/shadow50.png', new google.maps.Size(37, 34), new google.maps.Point(0,0), new google.maps.Point(9, 34));
var iconColor   = new google.maps.MarkerImage("http://www.geocodezip.com/mapIcons/marker_blue.png", new google.maps.Size(20, 34), new google.maps.Point(0,0), new google.maps.Point(9, 34));
var iconColora  = new google.maps.MarkerImage("http://www.cheboksary.ws/i/ost.png", new google.maps.Size(20, 34), new google.maps.Point(0,0), new google.maps.Point(9, 34));
var iconShadowa = new google.maps.MarkerImage("http://www.cheboksary.ws/i/ost_s.png", new google.maps.Size(37, 34), new google.maps.Point(0,0), new google.maps.Point(9, 34));

function CoordMapType(){}

var infowindow = new google.maps.InfoWindow();
//var infowindow = new google.maps.InfoWindow({ size: new google.maps.Size(250, 150) });
var infos      = new google.maps.InfoWindow();

CoordMapType.prototype.tileSize = new google.maps.Size(256, 256); CoordMapType.prototype.maxZoom  = 18;
CoordMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
	var div = ownerDocument.createElement('DIV');
	div.style.width = this.tileSize.width + 'px';
	div.style.height = this.tileSize.height + 'px';
	if(zoom >= 12 && zoom <= 18){
		tmpx = coord.x - (2584 << (zoom-12));
		tmpy = coord.y - (1272 << (zoom-12));
		tmpd = 5 << (zoom-12);
		if(tmpx >= 0 && tmpx < tmpd && tmpy >= 0 && tmpy < tmpd){
			div.style.backgroundImage = "url(http://www.cheboksary.ws/gug/"+zoom+"-tile-"+coord.x+"-"+coord.y+".png)";
		} else {
			div.style.backgroundImage = "url(http://mt1.google.com/vt/lyrs=m@152000000&hl=ru&x=" + coord.x + "&y=" + coord.y + "&z=" + zoom + "&s=Gali)";
		}
	} else {
		div.style.backgroundImage = "url(http://mt1.google.com/vt/lyrs=m@152000000&hl=ru&x=" + coord.x + "&y=" + coord.y + "&z=" + zoom + "&s=Gali)";
	}
	return div;
};
CoordMapType.prototype.name = "Карта"; CoordMapType.prototype.alt  = "Карта"; var coordinateMapType = new CoordMapType();

function CoordMapTypeOSM(){}
CoordMapTypeOSM.prototype.tileSize = new google.maps.Size(256, 256); CoordMapTypeOSM.prototype.maxZoom  = 18;
CoordMapTypeOSM.prototype.getTile = function(coord, zoom, ownerDocument) {
	var div = ownerDocument.createElement('DIV');
	div.style.width = this.tileSize.width + 'px';
	div.style.height = this.tileSize.height + 'px';
	div.innerHTML = "<img src='http://tile.openstreetmap.org/" + zoom + "/" + coord.x + "/" + coord.y + ".png'>";
	return div;
};
CoordMapTypeOSM.prototype.name = "Карта OSM"; CoordMapTypeOSM.prototype.alt  = "Карта OSM";
var coordinateMapTypeOSM = new CoordMapTypeOSM();

function CoordMapTypeWIKI(){}
CoordMapTypeWIKI.prototype.tileSize = new google.maps.Size(256, 256); CoordMapTypeWIKI.prototype.maxZoom  = 18;
CoordMapTypeWIKI.prototype.getTile = function(coord, zoom, ownerDocument) {
	var div = ownerDocument.createElement('DIV');
	div.style.width = this.tileSize.width + 'px';
	div.style.height = this.tileSize.height + 'px';
	i = coord.x%4+(coord.y%4)*4;
	div.innerHTML = "<img src='http://i"+i+".wikimapia.org/?x="+coord.x+"&y="+coord.y+"&zoom="+zoom+"&r=0&type=&lng=1'>";
	return div;
};
CoordMapTypeWIKI.prototype.name = "Карта WIKI"; CoordMapTypeWIKI.prototype.alt  = "Карта WIKI"; var coordinateMapTypeWIKI = new CoordMapTypeWIKI();
