
/** 
 * Этот файл создается автоматически, не изменяйте его.
 * @fileoverview Этот файл содержит пользовательские классы для работы с сервером 
 * {@link http://maps.karelia.ru maps.karelia.ru} 
 * Для работы, перед подключением этих класоов необходимо добавить, дополнительные функции
 * <b>&lt;script type='text/javascript' src='http://maps.karelia.ru/coreapi.aspx'&gt;&lt;/script&gt;</b><br />
 * и классы объектов <b>&lt;LINK href="http://maps.karelia.ru/userapi.css" type="text/css" rel="stylesheet"/&gt;</b> (в дальнейшем возможно, будут подключаться динамически)   
 * Параметры запроса к userapi.aspx?: <br />
 * <b>mf</b> - имя карты <br />
 * <b>tools</b> - набор инструментов.<br /> 
 * например, &lt;script type='text/javascript' src='http://maps.karelia.ru/userapi.aspx?mf=ptz2006&tools=INFO,PAN,QUERY,ZOOMIN,ZOOMOUT,REFMAP'&gt;&lt;/script&gt; 
 * <br> Готовый пример {@link ready-example-index.html API}
 * @author Sergei Navolotsky sergn@ptz.ru
 * @version 0.2
 */


 /**
 * Создает экземпляр класса MapLayer
 * @class MapLayer класс для определения слоя
 * @constructor 
 * @param {int} i индекс
 * @param {string} n имя
 * @param {boolean} v видимый или нет
 * @param {string} d описание
 */
MapLayer = function (i, n, v, d, nn){this.index=i;this.name=n;this.visible=v;this.desc=d;this.originalName=nn;}; 

 /**
 * Создает экземпляр класса UserMarker
 * @class MapLayer класс для определения слоя
 * @constructor 
 */
UserMarker = function(){}
UserMarker.prototype=    
       {
       /**
        * Координата x (гео)
        * @type {double} 
        */
       x:0.0,
       /**
        * Координата y (гео)
        * @type {double} 
        */
       y:0.0,
       /**
        * Подпись
        * @type {double} 
        */
       text:'',
        /**
        * Использовать или нет true/false 
        * @type {boolean} 
        */
        use:false
       }
/**
 * Создает новую карту
 * @constructor 
 * @class
 */
UserMap = function(){};
UserMap.prototype = 
{   
    transId:0,
     /**
    * @private    
    */
    siteURL:"",
   /**
    * @private    
    */
    serverURL:"http://maps.karelia.ru",
    /**
    * @private    
    */
    queryURL:'http://maps.karelia.ru/query.aspx',
    tools:[],    
    /**
    * Массив слоев карты {@link MapLayer}
    * @type {array}
    */    
    layers:null ,  
     /**
    * @private    
    */
    tematics:null,     
    /**
    * Адрес картинки загрузки, по умолчанию
    * {@link http://maps.karelia.ru/images/indicator_arrows_black.gif indicator_arrows_black.gif}
    * @type {string}    
    */
    waitImageURL:'http://maps.karelia.ru/images/indicator_arrows_black.gif',
     /**
    * @private    
    */
    mapCanvas:null,
     /**
    * @private    
    */
    enableLog:false,
    /**
    * Размеры карты в пикселах (ширина) карты
    * @type {int}
    */
    width:400,
    /**
    * Размеры карты в пикселах (высота) карты
    * @type {int}
    */
    height:400,
     /**
    * Результаты последнего запроса поиска или информации с карты
    * @type {DataSet}
    */
    resultSet:null, 
    /**
    * Объект {@link UserMarker}, позволяет подписать некоторый объект на карте.
    * @type {UserMapker}
    */
    marker:  null,       
    
    /**
    * Текущий центр карты , в географических координтах (x)
    * @type {double}
    */
    cx:44819.197725625,
    /**
    * Текущий центр карты , в географических координтах (y)
    * @type {double}
    */
    cy:43086.1950485,
    /**
    * Горизонтальный размер видимого фрагмента карты в метрах проекции. 
    * @type {double}
    */
    zoom:15451.10205,    
    /**
    * хранит массив состояний карты
    * например: (states[0].cx states[0].cy states[0].zoom) - изначальное состояние
    * @type {array}
    */    
    states:null,
    objectzoom:650, 
    minzoom:250, 
    maxzoom:16000, 
    
    defSearchLayer:'Строения', 
    /**
    * @private    
    */    
    zoombox:null,
    /**
    * @private    
    */
    mapfile:'ptz2006v3',
    /**
    * Состояние карты: 
    * 0 - не инициализирован, 1 - инициализирован, 2 - готов, 3 - загрузка карты, 4 - загрузка запроса
    * @type {int}
    */
    state:0 ,    
    /**
    * Рисовать или нет ScaleBar
    * null - определяется конфигурационным файлом,иначе рисовать или нет: true,false
    * @type {boolean}
    */
    drawscale:null ,    
    /**
    * @private    
    */
    mapTool:"",
    /**
    * @private    
    */
    maxzindex:3000,    
    /**
    * Пользователькое событие, вызывается когда заканчивается загрузка карты
    */
    ondrawend :function(){}, 
    /**
    * Пользователькое событие, вызывается когда при загрузке карты произошла ошибка
    */
    ondrawerror: function(){},
    /**
    * Пользователькое событие, при изменении соcтояния карты {@link UserMap#state}
    * @param state текущее состояние 
    */
    onstatechanged:function (state){},
    /**
    * Пользователькое событие, при получении результатов запроса {@link UserMap#resultSet}
    * @param {DataSet} res - результаты поиска. Содержит массив таблиц их строк и полей. см. пример.
    */
    onresults:function(res){},
    ondrawlayers:function(){},
    /**
    * Пользователькое событие, инструмент "линейка" 
    * @param {double} current - текущее растояние
    * @param {double} total - сумма расстояний всех измерений
    */
    onrullerchange:function(current,total){},
    /**
    * Пользователькое событие, инструмент "Подписать" 
    * @param {array} labels - массив объектов  Label {table, label, x, y}
    * table - слой на котором найдена подпись, 
    * label - подпись ,
    * x,y - географические координаты точки , где был применен инструмент
    */ 
    onlabelchange:function(labels){},
    /**
    * Пользователькое событие, результат вызова {@link UserMap#queryObject}
    * @param {object} {cx, cy, zoom}
    * table - слой на котором найдена подпись, 
    * label - подпись ,
    * x,y - географические координаты точки , где был применен инструмент
    */ 
    onobjectresults:function (obj){},
    /**
    * @private    
    */    
    onsetuptool:function (tool){} ,
    /**
    * @private    
    */    
    onmapload :function (map){}  ,
    
    authKey: '54slwqe01sbbnqa5o0dufp55',
    
    hitOffset: 30
};

/** 
 * @returns Расстояние между точками в географичеких координатах
 * @param {array int} pt1 массив из двух элементов x, y
 * @param {array int} pt2 массив из двух элементов x, y
 * @param {bool} bpix пиксльные или географические координаты
 */
UserMap.prototype.Distance =  function  (pt1, pt2, bpix)
                  {
                    var pth=Math.sqrt((pt1[0]-pt2[0])*(pt1[0]-pt2[0])+(pt1[1]-pt2[1])*(pt1[1]-pt2[1]));
                    
                    return bpix ? Math.round(pth/this.width*this.zoom):pth;                    
                  }
/** 
 * Сдвиг карты на % от показываемой ширины 
 * @param {string} dir направление сдвига t,l,b,r, tl, tr, bl, br
 * @param {int} val сдвиг, по умолчанию 30%, (1-100)
 */                  
UserMap.prototype.move = function (dir, val)
{                   
    if (this.state != 2   ) return;
    var d0 = (typeof(val)!='undefined'? val:30);
    var d = this.zoom*(d0/100) ;
    try
    {
        switch (dir)
        {
            case "l":
                this.cx = this.cx -  d;
                break;
            case "r":
                this.cx = this.cx +  d;
                break;
            case "t":
                this.cy = this.cy + d;
                break;
            case "b":
                this.cy = this.cy -  d;
                break;
            case "tl":
                this.cx = this.cx - d;
                this.cy = this.cy +  d;
                break;
            case "tr":
                this.cx = this.cx +  d;
                this.cy = this.cy +  d;
                break;
            case "bl":
                this.cy = this.cy -  d;
                this.cx = this.cx - d;
                break;
            case "br":
                this.cy = this.cy -  d;
                this.cx = this.cx +  d;
                break;
            default:
                return;
          }
          this.draw();
     }
     catch (e){}
}             
/** 
 * Пересчет координат изображения (пиксели) в географические
 * @returns {array} Массив из 2-х элементов x,y 
 * @param {int} picX x - координата
 * @param {int} picY y - координата
 */                  
UserMap.prototype.pixToGeo = function (picX, picY)
{    
    var x1 = picX; 
    var y1 = picY;
    
    var x0=this.width/2;
    var y0=this.height/2;
    
    var x=this.cx+((x1-x0)*this.zoom)/this.width;
    var y=this.cy+((-y1+y0)*this.zoom)/this.width;
    
    
    return [x,y];
}
/** 
 * Пересчет координат карты (метры) в пиксели
 * @returns {array} Массив из 2-х элементов x,y 
 * @param {int} geoX x - координата
 * @param {int} geoY y - координата
 */                  
UserMap.prototype.geoToPix = function (geoX, geoY)
{    
    var x1 = geoX; 
    var y1 = geoY;
        
    var x=Math.round((x1-this.cx)*this.width/this.zoom+this.width/2);
    var y=Math.round(-(y1-this.cy)*this.width/this.zoom+this.height/2);
    
    return [x,y];
}
/** 
 * Возврат в предыдущее состояние
 */ 
UserMap.prototype.back = function()
{
    if (this.states.length > 1)
    {
        this.states.pop();
        var state = this.states.pop();
        this.cx = state.cx;
        this.cy = state.cy;
        this.zoom = state.zoom;
        this.draw();        
    }
}
/** 
 * Возврат в предыдущее состояние
 */ 
UserMap.prototype.gotoState = function(i)
{
    if (this.states.length > i && i >=0)
    {
        var state = this.states[i];
        this.cx = state.cx;
        this.cy = state.cy;
        this.zoom = state.zoom;
        this.draw();        
    }
}

/**
* Рисовать или нет мосштаб карты
* @param {boolean} b - если null,рисовать или нет определяет конфиг. файл. 
* иначе true/false- рисовать или нет.
*/
UserMap.prototype.setDrawScale=function(b)
{
    this.drawscale = b;
    this.draw();
}
/** 
 * Установка размера карты
 * @param {int} w ширина карты в пикселях
 * @param {int} h высота карты в пикселях
 */ 
UserMap.prototype.setSize = function(w, h)
{
    this.width = w;
    this.height = h;
    
    
    var mc = xGetElementById(this.mapCanvas );
    var map = xGetElementById(this.mapCanvas +"_MAP");

    xWidth(this.mapCanvas +"_USERICONS", this.width);	
    xHeight(this.mapCanvas +"_USERICONS", this.width);
    
    this.draw();
}
/** 
 * Инициализация объекта карты, дб вызвана в window.onload
 * @param {string} el имя div элемента,в котором будет строятся объекты интерфейса карты
 * @param {int} w ширина карты в пикселях
 * @param {int} h высота карты в пикселях
 * @param {string} wi - url картинки, которая будет появляться при загрузках. необязательный.
 */
UserMap.prototype.initialize =function (el,w,h,wi,d)
{
		this.head = document.getElementsByTagName("head")[0];
    document.UserMap = this;
    if (this.state > 0 ) return;
    this.mapCanvas = el;  
    this.width =w;
    this.height =h;
    if (typeof(wi)!='undefined') this.waitImageURL = wi;
    this.marker = new UserMarker();
    this.layers = new Array();
    this.object = null;
    this.labels = null;
    this.objectIndex = -1;
    this.states = new Array();    
    var bDraw = (typeof(d)!="undefined"?d:true);
    
    /*
    Moving by grid??
    this.box_width = w  ;
    this.box_height= h  ;*/

   
    
    this.states[0] = this.evalJSON('{\"cx\":'+this.cx+',\"cy\":'+this.cy+',\"zoom\":'+this.zoom+'}');
    this.layers[0]=new MapLayer (0,'Железные дороги',true,'Железные дороги');this.layers[0].init=true;this.layers[0].baseicon='';this.layers[0].legends=new Array();this.layers[1]=new MapLayer (1,'Строения',true,'Строения');this.layers[1].init=true;this.layers[1].baseicon='';this.layers[1].legends=new Array();this.layers[2]=new MapLayer (2,'Острова',true,'Острова');this.layers[2].init=true;this.layers[2].baseicon='';this.layers[2].legends=new Array();this.layers[3]=new MapLayer (3,'Гидрография',true,'Гидрография');this.layers[3].init=true;this.layers[3].baseicon='';this.layers[3].legends=new Array();this.layers[4]=new MapLayer (4,'Растительность',true,'Растительность');this.layers[4].init=true;this.layers[4].baseicon='';this.layers[4].legends=new Array();this.layers[4].legends[0]=this.evalJSON('{"src":"ptz2006-2.gif","title":"Газон"}');this.layers[4].legends[1]=this.evalJSON('{"src":"ptz2006-4.gif","title":"Лес"}');this.tematics=new Array();this.tematics[0]=new MapLayer (0,'Остановки',false,'Остановки','Остановки_ГТ_О');this.tematics[0].legends=new Array();this.tematics[0].legends[0]=this.evalJSON('{"src":"http://maps.karelia.ru/portaldata/layer_images/ptz2006-tematic-2.gif","title":"Остановки"}');this.tematics[1]=new MapLayer (1,'№ 1',false,'№ 1','Троллейбус_N1');this.tematics[1].legends=new Array();this.tematics[2]=new MapLayer (2,'№ 2',false,'№ 2','Троллейбус_N2');this.tematics[2].legends=new Array();this.tematics[3]=new MapLayer (3,'№ 3',false,'№ 3','Троллейбус_N3');this.tematics[3].legends=new Array();this.tematics[4]=new MapLayer (4,'№ 4',false,'№ 4','Троллейбус_N4');this.tematics[4].legends=new Array();this.tematics[5]=new MapLayer (5,'№ 5',false,'№ 5','Троллейбус_N5');this.tematics[5].legends=new Array();this.tematics[6]=new MapLayer (6,'№ 6',false,'№ 6','Троллейбус_N6');this.tematics[6].legends=new Array();this.tematics[7]=new MapLayer (7,'№ 8',false,'№ 8','Троллейбус_N8');this.tematics[7].legends=new Array();this.tematics[8]=new MapLayer (8,'№ 1',false,'№ 1','Автобус_N1');this.tematics[8].legends=new Array();this.tematics[9]=new MapLayer (9,'№ 2',false,'№ 2','Автобус_N2');this.tematics[9].legends=new Array();this.tematics[10]=new MapLayer (10,'№ 3',false,'№ 3','Автобус_N3');this.tematics[10].legends=new Array();this.tematics[11]=new MapLayer (11,'№ 4',false,'№ 4','Автобус_N4');this.tematics[11].legends=new Array();this.tematics[12]=new MapLayer (12,'№ 5',false,'№ 5','Автобус_N5');this.tematics[12].legends=new Array();this.tematics[13]=new MapLayer (13,'№ 10',false,'№ 10','Автобус_N10');this.tematics[13].legends=new Array();this.tematics[14]=new MapLayer (14,'№ 11',false,'№ 11','Автобус_N11');this.tematics[14].legends=new Array();this.tematics[15]=new MapLayer (15,'№ 12',false,'№ 12','Автобус_N12');this.tematics[15].legends=new Array();this.tematics[16]=new MapLayer (16,'№ 13',false,'№ 13','Автобус_N13');this.tematics[16].legends=new Array();this.tematics[17]=new MapLayer (17,'№ 14',false,'№ 14','Автобус_N14');this.tematics[17].legends=new Array();this.tematics[18]=new MapLayer (18,'№ 15',false,'№ 15','Автобус_N15');this.tematics[18].legends=new Array();this.tematics[19]=new MapLayer (19,'№ 16',false,'№ 16','Автобус_N16');this.tematics[19].legends=new Array();this.tematics[20]=new MapLayer (20,'№ 17',false,'№ 17','Автобус_N17');this.tematics[20].legends=new Array();this.tematics[21]=new MapLayer (21,'№ 18',false,'№ 18','Автобус_N18');this.tematics[21].legends=new Array();this.tematics[22]=new MapLayer (22,'№ 19',false,'№ 19','Автобус_N19');this.tematics[22].legends=new Array();this.tematics[23]=new MapLayer (23,'№ 20',false,'№ 20','Автобус_N20');this.tematics[23].legends=new Array();this.tematics[24]=new MapLayer (24,'№ 21',false,'№ 21','Автобус_N21');this.tematics[24].legends=new Array();this.tematics[25]=new MapLayer (25,'№ 22',false,'№ 22','Автобус_N22');this.tematics[25].legends=new Array();this.tematics[26]=new MapLayer (26,'№ 23',false,'№ 23','Автобус_N23');this.tematics[26].legends=new Array();this.tematics[27]=new MapLayer (27,'№ 24',false,'№ 24','Автобус_N24');this.tematics[27].legends=new Array();this.tematics[28]=new MapLayer (28,'№ 25',false,'№ 25','Автобус_N25');this.tematics[28].legends=new Array();this.tematics[29]=new MapLayer (29,'№ 26',false,'№ 26','Автобус_N26');this.tematics[29].legends=new Array();this.tematics[30]=new MapLayer (30,'№ 27',false,'№ 27','Автобус_N27');this.tematics[30].legends=new Array();this.tematics[31]=new MapLayer (31,'№ 28',false,'№ 28','Автобус_N28');this.tematics[31].legends=new Array();this.tematics[32]=new MapLayer (32,'№ 29',false,'№ 29','Автобус_N29');this.tematics[32].legends=new Array();this.objectzoom=650;this.tools[0]='INFO';this.tools[1]='PAN';this.tools[2]='QUERY';this.tools[3]='ZOOMIN';this.tools[4]='ZOOMOUT';this.tools[5]='REFMAP';this.tools[6]='RULLER';this.tools[7]='LABEL';this.tools[8]='RASTER';this.mapTool='INFO';
        this.change_date = function (v)
        {
            if (this.state == 3) return;
            if (!this.dateIndex)
                this.dateIndex = this.rasterFiles.length - 2;
            if (v == 'last')
                this.dateIndex = this.rasterFiles.length - 2;
            else if (this.dateIndex+ v >= 0 && this.dateIndex + v <= this.rasterFiles.length - 2)    
            {
                this.dateIndex = this.dateIndex+ v;               
             }
              if (this.ondateindexchanged)
                    this.ondateindexchanged(this.dateIndex);
                    
                this.draw();
                            
        };
 
        
    this.createChilds();
         
    
    this.state = 1;
    this.onstatechanged(this.state);
       
    if (bDraw) 
        this.draw();    
           
    this.ondrawlayers();
}
/**
* @private    
*/
UserMap.prototype.jsonServerException=function(message)
{
    alert(message);
}
/**
* @private    
*/
UserMap.prototype.evalJSON = function (json)
{
    try
    {
        if (json=='')
        {            
            return null;    
        }
        var s = new String(json);
          !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
                s.replace(/"(\\.|[^"\\])*"/g, ''))) 
        var ob =  eval('(' + s + ')');
        return ob;
    }
    catch (e){return null;}
}


/**
* @private    
*/
UserMap.prototype.jsonObjectCallback=function (json)
{
   document.UserMap.hideLoading();
   document.UserMap.state = 2;
   document.UserMap.onstatechanged (this.state); 
  try
    {
        
         var ob =  this.evalJSON(json);
          
            if (typeof(ob)!="undefined")
            {
            		if (!ob.length)
            		{
                	this.cx = ob.x;
                	this.cy = ob.y;
                	
                	if (ob.zoom!=0)
                		this.zoom = ob.zoom;
            		}
            		else
            		{
            				var minx = 9999999999999;
						    		var maxx = -999999999999;
						    		var miny = 9999999999999;
						    		var maxy = -999999999999;
						    		for (var r in ob)
						    		{
						    				var x = ob[r].x;
						    				var y =  ob[r].y;
						    										    										    									    				
						    				if(x < minx) minx =  x;
						    				if(x > maxx)  maxx = x;
						    				
						    				
						    				if(y > maxy) maxy = y;
						    				if (y < miny)  miny = y;						    				
						    		}
						    		/*maxx +=umap.objectzoom;
						    		miny -=umap.objectzoom;
						    		maxy +=umap.objectzoom;
						    		miny -=umap.objectzoom; */
						    		this.cx = (maxx + minx)/2;
						    		this.cy = (maxy + miny)/2;						    		
						    		
						    		
						    		this.zoom = this.Distance ( [minx,miny], [maxx, maxy], false);;
            		}
            		
                this.onobjectresults(ob);
                this.draw();
            }
       
     }
     catch (e)
     {
       // alert('Callback:'+e.message);
        
     }    
    
}
/**
* @private    
*/
UserMap.prototype.jsonTextCallback=function (json)
{   
    document.UserMap.hideLoading();
    document.UserMap.state = 2;
    document.UserMap.onstatechanged (this.state); 
  
    try
    {
        
        if (json=='')
        {
            this.onresults(null);
            return;    
        }
        var s = new String(json);
          !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
                s.replace(/"(\\.|[^"\\])*"/g, ''))) 
        this.resutSet =  eval('(' + s + ')');

        
        
        this.onresults(this.resutSet);
     }
     catch (e)
     {
       // alert(e.message);
        this.resutSet = null;
     }    
    
}
/**
* @private    
*/
UserMap.prototype.jsonLoad = function()
{
    
    document.UserMap.hideLoading();
    document.UserMap.state = 2;
    document.UserMap.onstatechanged (this.state);    
}     
/**
* @private    
*/
UserMap.prototype.beforeQueryText=function(str)
{ 
    return true;   
}
/** 
 * Запрос о поиске текста на карте. Поиск будет происходить по слоям и полям этих слоев, установленных в конфигурации карты на сервере. 
 * Поиск полнотекстовый. В результат поиска будет доступен в {@link UserMap#onresults}
 * @param {string} str уникальный код объекта в слое карты 
 */
UserMap.prototype.queryText=function(str, layer, fulltext)
{    
    if (!this.beforeQueryText(str))
        return false;
    
    var url = this.queryURL+"?cmd=text&mf="+this.mapfile+".map&p="+(str);
    if (typeof(layer)!="undefined")
        url+=(":"+layer);
    if (typeof(fulltext)!="undefined")
        url+=(":"+fulltext);
    if (url.length > 2048) return false;
    
    var script = document.createElement("script");
    script.onload = this.jsonLoad;  
    script.src = url;
    
    script.type = "text/javascript";
    this.state = 4;
    this.showLoading();
    this.onstatechanged (this.state);    
    xAppendChild(document.body, script);       
    return true;
}

/** 
 * Запрос о поиске объета  на карте. Если объект будет найден, то текущие {@link UserMap#cx} , {@link UserMap#cy}, {@link UserMap#zoom} будут установлены, так чтобы показать  этот объект. 
 * @param {object} id уникальный код объекта в слое карты
 * @param {string} layer имя слоя карты, мб быть получено из {@link UserMap#layers} или из {@link UserMap#resultSet}
 * @param {string} mt подпись объекта, опустить если не нужна
 */
UserMap.prototype.queryObject=function(id, layer, d)
{
    var url = this.queryURL+"?cmd=object&mf="+this.mapfile+".map&p="+escape(id+":" +layer+ (typeof(d)!='undefined'?':1':'')) ;
               
/*    if (typeof(mt)!='undefined')
    {
     this.marker.use = (mt!=""); 
     this.marker.text = mt;
    }
    else this.marker.use = false; */
    
    var script = document.createElement("script");
    script.onload = this.jsonLoad;
    script.src = url;
    script.setAttribute("language", "javascript");
    script.type = "text/javascript";
    script.id = ++this.transId;
    if(typeof this.scriptCharset !='undefined')
	script.charset = this.scriptCharset;	
    this.state = 4;
    this.showLoading();
    this.onstatechanged (this.state);    
    xAppendChild(this.head, script);       
}


/**
* @private    
*/
UserMap.prototype.createChilds = function()
{
    
    var mc = xGetElementById(this.mapCanvas );
    mc.className +=" mapCanvas" ;
     
    mc.oncontextmenu=function(){return false;} 
    mc.ondragstart=function(){return false;} 
    
    

		if (xGetElementById(this.mapCanvas +"_MAP"))return;           
    var map = document.createElement("div");    
    map.id = this.mapCanvas +"_MAP";  
    map.className ="mapCanvas_MAP";    
    xAppendChild (mc, map);
    

    
    xAddEventListener (map, "mousedown", this.OnInfo, false);
       

    var mapimage = new Image();
    mapimage.id = this.mapCanvas +"_MAPIMAGE";  
    mapimage.galleryimg = "no";
   
    xAppendChild (map, mapimage);
    xHide (mapimage);
    
    
 
        
    var progress_image = document.createElement("div");
    progress_image.id = this.mapCanvas + "_PROGRESS";
    xAppendChild (mc, progress_image);
    
    var pimage = new Image();
    pimage.src = this.waitImageURL;    
    
    xAppendChild (progress_image, pimage);
    
    progress_image.className = "mapCanvas_PROGRESS";
    if (this.enableLog)
    {
        var debug = document.createElement("TEXTAREA");
        debug.id = this.mapCanvas+ "_LOG";
        xHeight(debug, 100);
        xWidth(debug, 400);
        xAppendChild (document.body, debug);
    }
    
    var zbox = document.createElement("div");
    zbox.id = this.mapCanvas + "_BOX";
    zbox.className = "mapCanvas_BOX";

    
    xAppendChild (mc, zbox);
    
    var draw_div = document.createElement("div");
    draw_div.id = this.mapCanvas + "_DRAW";
    xAppendChild (map, draw_div);    
    xAddEventListener (map, "mousedown", this.OnRuller, true);
    
    var info = document.createElement("div");
    info.id = this.mapCanvas + "_INFO";
    info.className = "mapCanvas_INFO";
    xAppendChild (document.body, info);
    
    
    xWidth(mc, this.width );
    xHeight(mc, this.height);
    xWidth(map, this.width );
    xHeight(map, this.height );
    
    
                  
}
 
/**
* @private    
*/   
UserMap.prototype.OnRuller=function (evt)
{
   if (document.UserMap.mapTool!="RULLER") return;
   var xEvt = new xEvent(evt);
   
   var b  = (xIE4Up?1:0);  
   if (evt.button == b)
   {
        var x=xEvt.offsetX;
        var y=xEvt.offsetY;
        var el = xEvt.target;        
        var key = new String(el.id);
       if (key.indexOf(document.UserMap.mapCanvas)==-1)
       {
         x = xLeft (el) + x;
         y = xTop (el) + y;
       }
        
       document.UserMap.jg.fillEllipse(x-3, y-3, 6, 6);
       if (document.UserMap.prevPoint!=null)
       {
            var pt = document.UserMap.geoToPix(document.UserMap.prevPoint[0], document.UserMap.prevPoint[1])            
            document.UserMap.jg.drawLine(pt[0],pt[1], x, y);
            
        }
        else
        {
            document.UserMap.object = new Array();  
                                        
        }  
        document.UserMap.jg.paint();                                         
        document.UserMap.prevPoint =  document.UserMap.pixToGeo(x, y);
        document.UserMap.objectIndex++;                                    
        document.UserMap.object [document.UserMap.objectIndex] =  document.UserMap.pixToGeo(x, y); 
        document.UserMap.showRuller();
    }
    else
    {
       document.UserMap.showRuller(true);
    }
    
    
}
/**
* @private    
*/  
UserMap.prototype.recalcRuller = function()
{
    if (document.UserMap.jg==null) document.UserMap.jg = new jsGraphics(this.mapCanvas+"_DRAW");
    if (document.UserMap.jg!=null)
    {
         this.jg.setColor("#ff0000");  
         document.UserMap.jg.clear();
         //this.prevPoint = this.pixToGeo(this.prevPoint[0], this.prevPoint[1])
         var pt1, pt2;
         for (var i=1; i <= this.objectIndex; i++)
         {
            
              pt1 = this.geoToPix(this.object[i-1][0], this.object[i-1][1]);  
              pt2 = this.geoToPix(this.object[i][0], this.object[i][1]);  
              this.jg.fillEllipse(pt1[0]-3, pt1[1]-3, 6, 6);
              this.jg.drawLine(pt1[0], pt1[1], pt2[0], pt2[1]); 
         }
         if (typeof(pt2)!="undefined")
            this.jg.fillEllipse(pt2[0]-3, pt2[1]-3, 6, 6);
         if (this.objectIndex >=1 )this.jg.paint();
         this.showRuller();
    }
}
/**
* @private    
*/  
UserMap.prototype.showRuller = function(bClear)
{
    var b = (typeof(bClear)!="undefined"?bClear:false);
    if (b&&document.UserMap.jg!=null)
    {
        document.UserMap.objectIndex=-1;
        document.UserMap.prevPoint  = null;
        document.UserMap.object = null;
        document.UserMap.jg.clear();
        xHide (this.mapCanvas+"_INFO");        
    }
    else if (this.objectIndex >= 1)
    {
        var d0 = this.Distance(this.object[this.objectIndex-1], this.object[this.objectIndex]); 
        var d = 0; 
                      
        for (var i=0; i < this.objectIndex; i++)
        {
            d+=this.Distance(this.object[i], this.object[i+1]);
        }
        
        this.onrullerchange(d0, d);        
    }
}
 
/**
* @private    
*/
UserMap.prototype.showLoading = function()
  {
      var mc = xGetElementById(this.mapCanvas );
      var mp = xGetElementById(this.mapCanvas + "_PROGRESS" );
      var map = xGetElementById(this.mapCanvas+"_MAP" );
      
      xLeft (mp, xWidth(mc)/2 - xWidth(mp)+2);
      xTop (mp, xHeight(mc)/2 - xHeight(mp)+2);
      xShow(mp);
      
       xDisableDrag(this.mapCanvas);    
        // xDisableDrag(this.mapCanvas+"_DRAW");   
         xDisableDrag(this.mapCanvas+"_MAP");                               
         
         if (typeof(document.UserRefMap)=='object') xDisableDrag(document.UserRefMap);
       
       map.className = "mapCanvas_MAP cursor-wait"; 
       
       this.state = 3;
       
       this.onstatechanged (this.state);
      
  };
/**
* @private    
*/  
UserMap.prototype.hideLoading = function()
{
       var mp = xGetElementById(this.mapCanvas + "_PROGRESS" );
       xHide(mp);
       this.state = 2;
         
      if (typeof(document.UserRefMap)=='object')  
        xEnableDrag(document.UserRefMap, document.UserRefMap.OnDragStart, document.UserRefMap.OnDrag, document.UserRefMap.OnDragEnd);                                          
      this.setupTool(this.mapTool, true);
      this.onstatechanged (this.state);                   
};
/**
* @private    
*/
UserMap.prototype.drawError =  function()
{
  document.UserMap.hideLoading ();
  alert ("Нераспознанная ошибка при загрузке карты! Перезагрузите страницу...");  
  document.UserMap.ondrawerror();  
}
/**
* @private    
*/
UserMap.prototype.drawEnd = function()
{   
    document.UserMap.hideLoading() ;
    
    var ml = xGetElementById(document.UserMap.mapCanvas+"_MAPIMAGE");

    var xEvt = new xEvent(null);
    var el = xEvt.srcElement;
    
      
    document.UserMap.ondrawend();  
    
    //ml.style.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+ml.src +"', sizingMethod='scale')";
        
    this.width = document.UserMap.width;
    this.height = document.UserMap.height;
    xShow (this);
    xMoveTo (document.UserMap.mapCanvas+"_MAP", xLeft(document.UserMap.mapCanvas), xTop(document.UserMap.mapCanvas));
    /*
    
*/
             
    document.UserMap.recalcRuller();
        
    
    var st = document.UserMap.evalJSON('{\"cx\":'+document.UserMap.cx+',\"cy\":'+document.UserMap.cy+',\"zoom\":'+document.UserMap.zoom+'}');    
    document.UserMap.states.push( st);
    if (typeof(document.UserRefMap)=="object")
        document.UserRefMap.updateRefRect();
    
    
     if (typeof document.UserMap.selection!="undefined")	  	
			document.UserMap.drawSelection (document.UserMap.selection); 
     if (document.UserMap.drawMarkers)	  	
     		document.UserMap.drawMarkers();
 
}
/** 
 * @private 
 */
UserMap.prototype.verifyZoom = function(z)
{
if (this.maxzoom>0 && this.minzoom>0)
    {
        if (z > this.maxzoom )
            return 1;
        if (z <  this.minzoom)
            return -1;
    }
    return 0;
}

/** 
 * Перерисовка карты  
 */
UserMap.prototype.draw = function ()
{
    var mc = xGetElementById(this.mapCanvas);   
    var map = xGetElementById(this.mapCanvas+"_MAP"); 
    this.showLoading();            
    var i = xGetElementById(this.mapCanvas+"_MAPIMAGE");
    i.onload  = this.drawEnd;    
    i.onerror = this.drawError;    
    i.src = this.getURL();
    
    
    
    xWidth(map, this.width);
    xHeight(map, this.height);
    map.style.width = this.width;
    map.style.height = this.height;
    
    xWidth(mc, this.width);
    xHeight(mc, this.height);
    mc.style.width = this.width;
    mc.style.height = this.height;
    
        


	  if (typeof document.UserMap.selection!="undefined")
	  	document.UserMap.clearSelection();
	  	
	 
	 if(document.UserMap.getMarkers)		   
	 {	 
	 		document.UserMap.getMarkers();
	 }

    
}
/**
* @private    
*/
UserMap.prototype.writeLog = function (str)
{
    var l = xGetElementById(this.mapCanvas+"_LOG");
    
    if (l!=null)
    {
        l.innerText +=(str+"\r\n");
    }
}
/**
* @private    
*/
UserMap.prototype.getLayersState =function()
{
    var strLayers = "";
    for (var i=0; i < this.layers.length;i++)
    {
        if (this.layers[i].init)
        {
            if (!this.layers[i].visible )
                strLayers+=this.layers[i].name+":";        
        }
        else
          if (this.layers[i].visible )
                strLayers+=this.layers[i].name+":";                         
    }    
    return strLayers;
}
/**
* @private    
*/
UserMap.prototype.getTematicsState=function()
{
var strLayers = "";
 for (var i=0; i < this.tematics.length;i++)
        if (this.tematics[i].visible)
            strLayers+=this.tematics[i].originalName+":";     
            return strLayers;
}
/**
* @private    
*/
UserMap.prototype.getURL = function ()
{   
    var url = this.serverURL+"/" +  this.mapfile + "-" + this.width  + "x" + this.height + ".map.png?cx=" + this.cx + "&cy=" + this.cy + "&zoom=" +this.zoom +
    (this.marker.use? "&mx=" + this.marker.x + "&my=" + this.marker.y + "&m="+escape(this.marker.text):'');
    var strLayers=this.getTematicsState();
    strLayers+=this.getLayersState();
    if (strLayers!="") url+= "&l="+escape(strLayers);
    if (this.drawscale!=null)
     url+=("&ds="+(this.drawscale?"1":"0"));
     
    if (this.dateIndex)
        url+=("&rfn="+(this.rasterFiles[this.dateIndex].fn));
        
    this.writeLog (url);
  
    return url; 
}

/**
* @private    
*/   
 UserMap.prototype.OnDragStart = function(ele, mx, my)
{
  window.status = ''; 
  ele.totalMX = 0;
  ele.totalMY = 0;
  //var mc = xGetElementById (document.UserMap.mapCanvas+"_MAP"); 
  setTimeout('xGetElementById (document.UserMap.mapCanvas+"_MAP").className ="mapCanvas_MAP cursor-grabbing"',20);
}
function test ()
{
  var mc = xGetElementById (document.UserMap.mapCanvas);
  
  var c = document.UserMap.pixToGeo(( xPageX(mc) - xPageX(document.ele)+document.UserMap.width/2), ( xPageY(mc) - xPageY(document.ele) + document.UserMap.height/2) );
 /**???**/
  {
    document.UserMap.cx = c[0];
    document.UserMap.cy = c[1];
  }
//  document.UserMap.zoombox = new String (( xPageX(mc) - xPageX(document.ele)) + ":" +( xPageY(mc) - xPageY(document..ele) ) + ":" + xWidth(ele) +":" + xHeight(ele));  
  //mc.className ="mapCanvas_MAP cursor-grab";
  document.UserMap.draw();  


}
/**
* @private    
*/
UserMap.prototype.OnDrag = function(ele, mdx, mdy)
{ 
  var x = xLeft(ele) + mdx;
  var y = xTop(ele) + mdy;
  
  
  xMoveTo(ele, x, y); 

         
}
/**
* @private    
*/
 UserMap.prototype.OnDragEnd = function(ele, mx, my)
{
  var mc = xGetElementById (document.UserMap.mapCanvas);
  
  var c = document.UserMap.pixToGeo(( xPageX(mc) - xPageX(ele)+document.UserMap.width/2), ( xPageY(mc) - xPageY(ele) + document.UserMap.height/2) );
 /**???**/
  {
    document.UserMap.cx = c[0];
    document.UserMap.cy = c[1];
  }
//  document.UserMap.zoombox = new String (( xPageX(mc) - xPageX(ele)) + ":" +( xPageY(mc) - xPageY(ele) ) + ":" + xWidth(ele) +":" + xHeight(ele));  
  //mc.className ="mapCanvas_MAP cursor-grab";
  document.UserMap.draw();  
}

/**
* @private    
*/   
UserMap.prototype.ResizeStart=function(ele, mx, my)
{        
   var box = xGetElementById (document.UserMap.mapCanvas+"_BOX");
   var mc = xGetElementById (document.UserMap.mapCanvas);
   
   var e = new xEvent(null);
   xShow(box);
   xLeft (box, mx- xPageX(mc));
   xTop (box, my - xPageY(mc));
   xWidth(box, 1);
   xHeight(box, 1);   
   ele.startPoint = [xLeft (box), xTop(box)];
   ele.point = null;
   
  
   
}
/**
* @private    
*/
UserMap.prototype.OnResize=function(ele, mdx, mdy)
{
  var box = xGetElementById (document.UserMap.mapCanvas+"_BOX"); 
  var l,t,w, h;
  
  if (ele.point==null)
    ele.point = [ele.startPoint[0]+mdx, ele.startPoint[1] + mdy];
  else
    ele.point = [ele.point[0]+mdx, ele.point[1] + mdy];
    
    
 l = Math.min(ele.point[0],ele.startPoint[0] );
 t = Math.min(ele.point[1],ele.startPoint[1] );
 

 w = Math.abs(ele.startPoint[0] - ele.point[0]);
 h = Math.abs(ele.startPoint[1] - ele.point[1]);
 xLeft(box,l);
 xTop(box, t);
 xWidth(box, w);
 xHeight(box,h);
 
 
 
}
/**
* @private    
*/
UserMap.prototype.OnResizeEnd=function(ele, mx, my)
{
    var mc = xGetElementById (document.UserMap.mapCanvas);
    var box = xGetElementById (document.UserMap.mapCanvas+"_BOX");      
    
    var c = document.UserMap.pixToGeo(xOffsetLeft(box) +xWidth(box)/2, xOffsetTop(box) + xHeight(box)/2);    
    var z = document.UserMap.Distance([xOffsetLeft(box), 0], [xOffsetLeft(box)+xWidth(box), 0], true);
    
    
      
   
      
    
    document.UserMap.cx = c[0];
    document.UserMap.cy = c[1];
    var oldzoom = document.UserMap.zoom;
    
    if (xWidth(box) > 5 && document.UserMap.mapTool=="ZOOMIN")
        document.UserMap.zoom = z;
    else if (document.UserMap.mapTool=="ZOOMIN")
    {
        document.UserMap.zoom = document.UserMap.zoom/=2;
     }
    else
        document.UserMap.zoom = document.UserMap.zoom*=2;
    
    box.style.width = "1px";
    box.style.height = "1px";
    xHide(box);
    
    var v = document.UserMap.verifyZoom(document.UserMap.zoom);
    if ( v > 0)
        document.UserMap.zoom = document.UserMap.maxzoom;           
    else if ( v < 0)
        document.UserMap.zoom = document.UserMap.minzoom;
    
    if (v!=0)document.UserMap.setupTool ("PAN", true);        
    
    document.UserMap.draw();
    
    
   
}
 
 /**
* @private    
*/
UserMap.prototype.createMarker=function(pt)
{
   var str = pt[0]+":" + pt[1] + ":" + this.width + ":" + this.height + 
            ":" + this.cx + ":" + this.cy + ":" 
            + this.zoom;
    var url = this.queryURL+"?cmd=label&mf="+this.mapfile+".map&p="+escape(str)+"&l="+ escape(this.getLayersState()+this.getTematicsState());  
   
    var script = document.createElement("script");
    script.onload = this.jsonLoad;
    script.src = url;
    script.type = "text/javascript";
    this.state = 4;
    this.showLoading();
    this.onstatechanged (this.state);    
    xAppendChild(document.body, script);
      
}

UserMap.prototype.jsonLabelCallback = function(res)
{
    this.hideLoading();
    this.state = 2;
    this.onstatechanged (this.state); 
    
    try
    {
   
        if (res!='')
        {
    
            var ob = this.evalJSON(res); 
            this.labels = ob;           
            this.onlabelchange (ob);
        
        }
    }
    catch (e) {}
}
 
/**
* @private    
*/
UserMap.prototype.beforeClickResults=function (pt)
{
    return true;
}
 /**
* @private    
*/
UserMap.prototype.getClickResults=function(pt)
{
    if (!this.beforeClickResults(pt))return;
    var str = pt[0]+":" + pt[1] + ":" + this.width + ":" + this.height + 
            ":" + this.cx + ":" + this.cy + ":" 
            + this.zoom;
    var url = this.queryURL+"?cmd=point&mf="+this.mapfile+".map&p="+escape(str)+"&l="+ escape(this.getLayersState()+this.getTematicsState());   
    var script = document.createElement("script");
    script.onload = this.jsonLoad;
    script.src = url;
    script.type = "text/javascript";
    script.setAttribute("language", "javascript");
    this.state = 4;
    script.id = ++this.transId;
    this.showLoading();
    if(typeof this.scriptCharset !='undefined')script.charset = this.scriptCharset;	

    this.onstatechanged (this.state);    
    xAppendChild(this.head, script);
}
/**
* @private    
*/
UserMap.prototype.OnInfo=function(evt)
{

    if (document.UserMap.state!=2)return;
    if (document.UserMap.mapTool!="INFO" && document.UserMap.mapTool!="LABEL") return;
    
    var xEvt = new xEvent(evt);   
    
    if (document.UserMap.mapTool=="INFO")    
    {    
    		/*if (document.UserMap.hitMarkersTest)
    		{
    			
    			 var p = document.UserMap.hitMarkersTest([xEvt.offsetX, xEvt.offsetY]);
    			 if (p)
    			 		return;
    			 else
    			 document.UserMap.getClickResults([xEvt.offsetX, xEvt.offsetY]);
    			 
    		}
    		else    		*/
        	document.UserMap.getClickResults([xEvt.offsetX, xEvt.offsetY]);
     }
    else
        document.UserMap.createMarker([xEvt.offsetX, xEvt.offsetY]);
        
}   


/**
    * Выбрать инструмент карты.       
    * @param {string} tool 
    * PAN - движение,
    * ZOOMIN - приблизить,
    * ZOOMOUT - уменьшить,
    * INFO - информация,
    * LABEL - подписать,
    * RULLER - линейка     
    * @param {boolean} reset - сбросить настройки текущего инструмента
    */
UserMap.prototype.setupTool = function (tool, reset)
{
  var b = typeof(reset)=="undefined"?false:reset;
  if (tool == this.mapTool&&!b) return;
  
  //Disable drag , resize on all
  xDisableDrag(this.mapCanvas);    
  xDisableDrag(this.mapCanvas+"_MAP");    
  var mc = xGetElementById(this.mapCanvas+"_MAP");
  var mi = mc;//xGetElementById(this.mapCanvas+"_MAPIMAGE");
  var canvas = xGetElementById(this.mapCanvas);
  this.writeLog ("Setup tool:" + tool);
  
  mc.className = "mapCanvas_MAP";
  switch (tool)
  {
  
    case "PAN":       
        xEnableDrag(mc, this.OnDragStart, this.OnDrag, this.OnDragEnd);
        //mc.className +=" cursor-grab";
        mi.className +=" cursor-grab";
        break;
         
    case "ZOOMIN":
                              
        xEnableDrag(mc, this.ResizeStart, this.OnResize, this.OnResizeEnd);
        //mc.style.cursor="";//url("+this.serverURL+"/images/cur/zoomin.cur)";                               ;
        //mc.className +=" cursor-zoom-in";
        mi.className +=" cursor-zoom-in";
        break;
         

    case "ZOOMOUT":
                      
        xEnableDrag(mc, this.ResizeStart, this.OnResize, this.OnResizeEnd);             
        //mc.className +=" cursor-grab";
        //mc.className +=" cursor-zoom-out";
        mi.className +=" cursor-zoom-out";
        break;
    
  case "RULLER":       
        var obj = mc;      
        var dc = xGetElementById(this.mapCanvas+"_DRAW");
        
        xLeft(dc, xLeft(obj));
        xTop(dc, xTop(obj));
        xWidth(dc, xWidth(obj));
        xHeight(dc,xHeight(obj));                        
        
        if (this.jg==null) this.jg = new jsGraphics(this.mapCanvas+"_DRAW");
        this.jg.setColor("#ff0000");  
                                      
        //mc.style.cursor = "crosshair";         
        //mc.className +=" cursor-area";
        mi.className +=" cursor-area";
        
       break;      
 
  case "INFO":          
        //mc.style.cursor = "help"; 
        //mc.className +=" cursor-help";
        mi.className +=" cursor-help";
        break;                  
              
    case "LABEL": 
        mi.className +=" cursor-area";
        //mc.className +=" cursor-area";
        break;
          
   default:        
      {
        if (typeof(this.customTools)!="undefined")
        {
          for (var i=0; i < this.customToolsCount; i++)
          {
            if (this.customTools[i].name == tool)
            {
              //mc.className+= (" " + this.customTools[i].cursorStyle);
             	mi.className+= (" " + this.customTools[i].cursorStyle);
              //xGetElementById(this.mapCanvas + "_MAPIMAGE").style.cursor = this.customTools[i].cursorStyle;
              
              break;
            }
          }
        }
      }
       // mc.style.cursor = ""; 
  }
  this.mapTool = tool;      
  this.onsetuptool (this.mapTool);
}
 
 
  /**
 * Создает экземпляр класса UserRefMap
 * @class UserRefMap класс для карты указателя.
 * @requires UserMap 
 * @constructor 
 */
 UserRefMap = function (){}
 UserRefMap.prototype=
  {
  /**
  * @private
  */
        serverURL:"http://maps.karelia.ru",        
        /**
    * Размеры карты - индекса в пикселах (ширина) карты
    * @type {int}
    */
        width:133,
    /**
    * Размеры карты - индекса в пикселах (ширина) карты
    * @type {int}
    */            
        height:133 ,
         /**
         * Текущий центр карты - индекса , в географических координтах (x)
          * @type {double}
        */
        cx:44819.197725625,
         /**
    * Текущий центр карты - индекса, в географических координтах (Y)
    * @type {double}
    */
        cy:43086.1950485,
 /**
    * Горизонтальный размер видимого фрагмента карты - индекса в метрах проекции. 
    * @type {double}
    */        
        zoom:15451.10205,
/**
  * @private
  */        
        refMap:null         
  }
   /**
 * Инициализирует карту - индекс
 * @param {object} um объект карты {@link UserMap}
 * @param {string} el имя div элемента,в котором будет строятся объекты интерфейса карты-индекса
 * @param {int} w ширина карты в пикселях
 * @param {int} h высота карты в пикселях
 * @param {string} c цвет рамки индексного прямоугольника, по умолчанию #ff0000. необязательный.
 */
  UserRefMap.prototype.initialize =function(um, el,w,h, c)
  {
    var refmap_p = xGetElementById(el);
    
    
    this.width = w;
    this.height=h;
    
    var refmap = document.createElement("div");
    refmap.id = "mapCanvas_REFMAP";
    this.refMap = "mapCanvas_REFMAP";
    refmap.className = "mapCanvas_REFMAP";
    
    xAppendChild (refmap_p, refmap);   
    
    
    
    var refimage = new Image();
    refimage.width = w;
    refimage.id="mapCanvas_REFMAP_IMG";
    refimage.height = h;
    refimage.style.left="0";
    refimage.style.top="0";
    
    
        
    refimage.src = this.serverURL +"/"+ um.mapfile +"-" +this.width+"x"+this.height+".smallmap.png";
    document.UserMap.writeLog(refimage.src);
    xAppendChild (refmap, refimage);
    
    xLeft(refmap, 0);
    xTop(refmap, 0);
    xWidth(refmap, this.width);
    xHeight(refmap, this.height);
        
    var refmaprect = document.createElement("div");
    var st = "1px solid "; 
    if (typeof(c)!="undefined")st += c;
    else st+="#ff0000;";
          
    refmaprect.style.border = st;
    refmaprect.id = this.refMap+"_REFMAP_RECT";
    refmaprect.className = "mapCanvas_REFMAP_RECT";
    xAppendChild (refmap, refmaprect);        
    
    document.UserRefMap = this;
    
    xShow(refmaprect);
    xEnableDrag(refmap, this.OnDragStart, this.OnDrag, this.OnDragEnd);
  }
/**
* @private    
*/  
 UserRefMap.prototype.OnDragStart=function(ele, mx, my)
{
    var mc = xGetElementById (document.UserRefMap.refMap);
   var mRect = xGetElementById (document.UserRefMap.refMap + "_REFMAP_RECT");
  xLeft(mRect, (mx-xPageX(mc)) - xWidth(mRect)/2);
  xTop(mRect, (my -xPageY(mc))-  xHeight(mRect)/2);
  window.status = "";
 
}
/**
* @private    
*/
 UserRefMap.prototype.OnDrag=function(ele, mx, my)
{
    var mRect = xGetElementById (document.UserRefMap.refMap+ "_REFMAP_RECT");
    xMoveTo(mRect, xLeft(mRect) + mx, xTop(mRect) + my);
  //  window.status = mx + " " + my;
    ele.totalMX  +=mx;
    ele.totalMY +=my;  
}
/**
* @private    
*/
 UserRefMap.prototype.OnDragEnd=function(ele, mx, my)
{
   var x,y,x1,y1,x0,y0;
   var mRect = xGetElementById (document.UserRefMap.refMap + "_REFMAP_RECT");
        
    var mc = xGetElementById (document.UserRefMap);
    x1 = xOffsetLeft(mRect) + xWidth(mRect)/2; 
    y1 = xOffsetTop(mRect) + xHeight(mRect)/2;
    document.UserMap.writeLog ("CENTER: " + x1 + " : " + y1);
    x0=document.UserRefMap.width/2;
    y0=document.UserRefMap.height/2;
    
    x=document.UserRefMap.cx+((x1-x0)*document.UserRefMap.zoom)/document.UserRefMap.width;
    y=document.UserRefMap.cy+((-y1+y0)*document.UserRefMap.zoom)/document.UserRefMap.width;
    
    
    document.UserMap.cx = x;
    document.UserMap.cy = y;
    
    document.UserMap.writeLog ("REFCENTER: " + x +" : " + y);
             
    document.UserMap.draw();
      
    return false;
  
}
/**
* @private    
*/
UserRefMap.prototype.updateRefRect  = function () 
{
    var x,y,x1,y1,x0,y0,s;
    
    x=document.UserMap.cx-document.UserMap.zoom/2;
    y=document.UserMap.cy+document.UserMap.zoom/2*document.UserMap.height/document.UserMap.width;
    x0=(x-this.cx)*this.width/this.zoom+this.width/2;
    y0=-(y-this.cy)*this.width/this.zoom+this.height/2;
    
    
    x=document.UserMap.cx+document.UserMap.zoom/2;
    y=document.UserMap.cy-document.UserMap.zoom/2*document.UserMap.height/document.UserMap.width;
    x1=Math.round((x-this.cx)*this.width/this.zoom+this.width/2);
    y1=Math.round(-(y-this.cy)*this.width/this.zoom+this.height/2);
    
    document.UserMap.writeLog("y:"+(y1-y0));
    
    var mRect = xGetElementById(document.UserRefMap.refMap+"_REFMAP_RECT");    
    
        
    var w = Math.round(x1-x0);
    var h = Math.round(y1-y0);
    
    xLeft(mRect, Math.round(x0));    
    xTop( mRect, Math.round(y0));
    if (w <= 5) w = 5;
    if (h <= 5) h = 5;    
    w = xWidth (mRect, w);
    h = xHeight(mRect, h);
       
    document.UserMap.writeLog("W:" + w + "H:" + h);
    xZIndex (mRect, document.UserMap.maxzindex++); 
    xShow(mRect);           
    document.UserMap.writeLog("RECT: " +xLeft(mRect) + " : " + xTop( mRect) +" : " + xWidth (mRect) + " : " + xHeight(mRect));                                 
  }
 
                
/**
* @private    
*/
UserMap.prototype.findLayer=function(name)
{
    for(var i=0; i < this.tematics.length; i++)
        if (name==this.tematics[i].originalName)
            return this.tematics[i];
    for(var i=0; i < this.layers.length; i++)
        {        
        if (name==this.layers[i].name)
            return this.layers[i];
         }
           
    return null;
}
 

/**
* @private    
*/
UserMap.prototype.onCustomTool=function(evt)
{
  var xEvt = new xEvent(evt);         
  var mapEvt = new Object();
  mapEvt.screenPix = [xEvt.offsetX, xEvt.offsetY];
  mapEvt.geoPix  = document.UserMap.pixToGeo(xEvt.offsetX, xEvt.offsetY);
  for (var i=0; i < document.UserMap.customToolsCount; i++)
  {
  
    if (document.UserMap.customTools[i].name==document.UserMap.mapTool)
    {
      document.UserMap.customTools[i].onmousedown(mapEvt);
      break;
    }
  }
}
/**
* @private    
*/
UserMap.prototype.addCustomTool=function(name, onmousedown, cursorStyle)
{
   if (typeof(this.customTools)=="undefined")
   {
      this.customTools=new Array();
      this.customToolsCount = 0;
    var map = xGetElementById (this.mapCanvas +"_MAP");
    xAddEventListener (map, "mousedown", this.onCustomTool, false);
   }
    
  this.customTools [this.customToolsCount] ={"name": name, "onmousedown": onmousedown, "cursorStyle":cursorStyle} ;
  
  this.customToolsCount++;  
}


/** 
 * Запрос о поиске текста на карте c подсветкой. Поиск будет происходить по слоям и полям этих слоев, установленных в конфигурации карты на сервере. 
 * Поиск полнотекстовый. В результат поиска будет доступен в {@link UserMap#onresults}
 * @param {string} str уникальный код объекта в слое карты 
 */
UserMap.prototype.queryTextWithSelect=function(str, layer, fulltext)
{    
    if (!this.beforeQueryText(str))
        return false;
    
    var url = this.queryURL+"?cmd=textselect&mf="+this.mapfile+".map&p="+(str);
    if (typeof(layer)!="undefined")
        url+=(":"+layer);
    if (typeof(fulltext)!="undefined")
        url+=(":"+fulltext);
    if (url.length > 2048) return false;
    
    var script = document.createElement("script");
    script.onload = this.jsonLoad;  
    script.src = url;
    
    script.type = "text/javascript";
    this.state = 4;
    this.showLoading();
    this.onstatechanged (this.state);    
    xAppendChild(document.body, script);       
    return true;
}