// Установить совместимость с Prototype jQuery.noConflict(); // Рсширение базового класса Number для удобности обсчетов Number.prototype.toRad = function() { return this * Math.PI / 180; } Number.prototype.toDeg = function() { return this * 180 / Math.PI; } // Подгрузка API карт google.setOnLoadCallback(function() { google.load("maps", "2.x", { "language": GRoads.lang, "hl": GRoads.lang, "other_params": "sensor=false", "callback": GRoads.init }); }); /** * Класс GRoads для отрисовки путей на картах Google Maps * * @class * @requires Google Maps API * @requires Prototype * @requires jQuery * @author Nergal */ var GRoads = { /** * Константы ошибок */ ER_FIRST_CITY_NOT_SET : 2, ER_SECOND_CITY_NOT_SET : 4, ER_FIRST_CITY_NOT_FOUND : 8, ER_SECOND_CITY_NOT_FOUND: 16, ER_CITY_NOT_FOUND : 32, ER_WRONG_DATE : 64, /** * Переменные */ map : null, manager : null, gDir : null, way : {}, waypoints : [], hash : [], cached : false, /** * Переменные * * @private */ _last_overlay : null, _fake_zoom : false, _points : [], _brand : [], /** * Предустановленные переменные */ lang : location.href.match(/meteoprog[\.a-z]+\/([a-z]+)\//)[1], coord : { 'x': '51.181', 'y': '71.428' }, /** * Конструктор класса * * @constructor */ init: function() { var self = GRoads; //Marker Manager eval(function(p,a,c,k,e,r){e=function(c){return(c< a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('5 4(c,b){2 e=3;e.13=c;e.D=c.1k();e.1h=c.1V().1N();b=b||{};e.N=4.1f;2 g=c.29();2 h=g[0].1o();l(2 i=0;ih){h=f}}e.p=b.1J||h;e.18=b.1E;e.m=b.15||C;2 d;7(28 b.1s==="24"){d=b.1s}11{d=4.1q}e.1p=w q(-d,d);e.1j=w q(d,-d);e.1Y=d;e.B=[];e.H=[];e.H[e.p]=[];e.s=[];e.s[e.p]=0;X.1e(c,"1U",e,e.1d);e.r=5(a){c.1L(a);e.G--};e.t=5(a){7(e.m){c.1G(a);e.G++}};e.U();e.G=0;e.8=e.V()}4.1f=1C;4.1q=1z;4.1w=1x;4.6.U=5(){2 a=3;2 c=4.1w;l(2 b=0;b<=a.p;++b){a.H[b]=[];a.s[b]=0;a.B[b]=o.2c(c/a.N);c<<=1}};4.6.27=5(){2 a=3;a.v(a.8,a.r);a.U()};4.6.n=5(a,c,b){2 d=3.1h.25(a,c);9 w 23(o.1r((d.x+b.22)/3.N),o.1r((d.y+b.1Z)/3.N))};4.6.10=5(e,a,f){2 b=e.Z();e.1n=a;7(3.18){X.1e(e,"1m",3,3.1l)}2 d=3.n(b,f,q.A);l(2 c=f;c>=a;c--){2 g=3.Y(d.x,d.y,c);g.1i(e);d.x=d.x>>1;d.y=d.y>>1}};4.6.F=5(e){2 a=3;2 c=a.8.J<=e.y&&e.y<=a.8.I;2 f=a.8.M;2 d=f<=e.x&&e.x<=a.8.K;7(!d&&f<0){2 b=a.B[a.8.z];d=f+b<=e.x&&e.x<=b-1}9 c&&d};4.6.1l=5(e,i,g){2 c=3;2 a=c.p;2 f=O;2 h=c.n(i,a,q.A);2 d=c.n(g,a,q.A);1g(a>=0&&(h.x!==d.x||h.y!==d.y)){2 b=c.L(h.x,h.y,a);7(b){7(c.W(b,e)){c.Y(d.x,d.y,a).1i(e)}}7(a===c.D){7(c.F(h)){7(!c.F(d)){c.r(e);f=C}}11{7(c.F(d)){c.t(e);f=C}}}h.x=h.x>>1;h.y=h.y>>1;d.x=d.x>>1;d.y=d.y>>1;--a}7(f){c.u()}};4.6.1T=5(e){2 c=3;2 b=c.p;2 a=O;2 f=e.Z();2 d=c.n(f,b,q.A);1g(b>=0){2 g=c.L(d.x,d.y,b);7(g){c.W(g,e)}7(b===c.D){7(c.F(d)){c.r(e);a=C}}d.x=d.x>>1;d.y=d.y>>1;--b}7(a){c.u()}c.s[e.1n]--};4.6.1S=5(b,a,c){2 d=3.R(c);l(2 i=b.E-1;i>=0;i--){3.10(b[i],a,d)}3.s[a]+=b.E};4.6.R=5(a){9 a||3.p};4.6.1Q=5(a){2 b=0;l(2 z=0;z<=a;z++){b+=3.s[z]}9 b};4.6.1P=5(e,b,a){2 d=3;2 h=w 1O(e,b);2 g=d.n(h,a,q.A);2 f=w 1M(h);2 c=d.L(g.x,g.y,a);7(c!=1b){l(2 i=0;i< c.E;i++){7(e==c[i].1a().1K()&&b==c[i].1a().T()){f=c[i]}}}9 f};4.6.1I=5(e,a,c){2 b=3;2 f=3.R(c);b.10(e,a,f);2 d=b.n(e.Z(),b.D,q.A);7(b.F(d)&&a<=b.8.z&&b.8.z<=f){b.t(e);b.u()}3.s[a]++};19.6.1H=5(a){2 b=3;9(b.M<=a.x&&b.K>=a.x&&b.J<=a.y&&b.I>=a.y)};4.6.Y=5(x,y,z){2 b=3.H[z];7(x<0){x+=3.B[z]}2 c=b[x];7(!c){c=b[x]=[];9(c[y]=[])}2 a=c[y];7(!a){9(c[y]=[])}9 a};4.6.L=5(x,y,z){2 a=3.H[z];7(x<0){x+=3.B[z]}2 b=a[x];9 b?b[y]:1b};4.6.17=5(j,b,c,e){b=o.S(b,3.p);2 i=j.1F();2 f=j.1D();2 d=3.n(i,b,c);2 g=3.n(f,b,e);2 a=3.B[b];7(f.T()< i.T()||g.x=a){d.x=0;g.x=a-1}2 h=w 19([d,g]);h.z=b;9 h};4.6.V=5(){2 a=3;9 a.17(a.13.1R(),a.D,a.1p,a.1j)};4.6.1d=5(){2 a=3;a.16(3,3.1c,0)};4.6.16=5(b,a,c){9 1B.1A(5(){a.1W(b)},c)};4.6.1X=5(){9 3.m?C:O};4.6.1y=5(){9!3.m};4.6.15=5(){3.m=C;3.P()};4.6.20=5(){3.m=O;3.P()};4.6.21=5(){3.m=!3.m;3.P()};4.6.P=5(){2 a=3;7(a.G>0){a.v(a.8,a.r)}7(a.m){a.v(a.8,a.t)}a.u()};4.6.1c=5(){2 a=3;a.D=3.13.1k();2 b=a.V();7(b.2d(a.8)&&b.z===a.8.z){9}7(b.z!==a.8.z){a.v(a.8,a.r);7(a.m){a.v(b,a.t)}}11{a.14(a.8,b,a.1v);7(a.m){a.14(b,a.8,a.1u)}}a.8=b;a.u()};4.6.u=5(){X.2b(3,"1m",3.8,3.G)};4.6.v=5(b,a){l(2 x=b.M;x<=b.K;x++){l(2 y=b.J;y<=b.I;y++){3.Q(x,y,b.z,a)}}};4.6.Q=5(x,y,z,a){2 b=3.L(x,y,z);7(b){l(2 i=b.E-1;i>=0;i--){a(b[i])}}};4.6.1v=5(x,y,z){3.Q(x,y,z,3.r)};4.6.1u=5(x,y,z){3.Q(x,y,z,3.t)};4.6.14=5(c,d,a){2 b=3;b.1t(c,d,5(x,y){a.2a(b,[x,y,c.z])})};4.6.1t=5(j,k,b){2 f=j.M;2 a=j.J;2 d=j.K;2 h=j.I;2 g=k.M;2 c=k.J;2 e=k.K;2 i=k.I;2 x,y;l(x=f;x<=d;x++){l(y=a;y<=h&&y< c;y++){b(x,y)}l(y=o.12(i+1,a);y<=h;y++){b(x,y)}}l(y=o.12(a,c);y<=o.S(h,i);y++){l(x=o.S(d+1,g)-1;x>=f;x--){b(x,y)}l(x=o.12(f,e+1);x<=d;x++){b(x,y)}}};4.6.W=5(a,c,b){2 d=0;l(2 i=0;i< a.E;++i){7(a[i]===c||(b&&a[i]===c)){a.26(i--,1);d++}}9 d};',62,138,'||var|this|MarkerManager|function|prototype|if|shownBounds_|return||||||||||||for|show_|getTilePoint_|Math|maxZoom_|GSize|removeOverlay_|numMarkers_|addOverlay_|notifyListeners_|processAll_|new||||ZERO|gridWidth_|true|mapZoom_|length|isGridPointVisible_|shownMarkers_|grid_|maxY|minY|maxX|getGridCellNoCreate_|minX|tileSize_|false|refresh|processCellMarkers_|getOptMaxZoom_|min|lng|resetManager_|getMapGridBounds_|removeFromArray_|GEvent|getGridCellCreate_|getPoint|addMarkerBatch_|else|max|map_|rectangleDiff_|show|objectSetTimeout_|getGridBounds_|trackMarkers_|GBounds|getLatLng|undefined|updateMarkers_|onMapMoveEnd_|bind|DEFAULT_TILE_SIZE_|while|projection_|push|nePadding_|getZoom|onMarkerMoved_|changed|MarkerManager_minZoom|getMaximumResolution|swPadding_|DEFAULT_BORDER_PADDING_|floor|borderPadding|rectangleDiffCoords_|addCellMarkers_|removeCellMarkers_|MERCATOR_ZOOM_LEVEL_ZERO_RANGE|256|isHidden|100|setTimeout|window|1024|getNorthEast|trackMarkers|getSouthWest|addOverlay|containsPoint|addMarker|maxZoom|lat|removeOverlay|GMarker|getProjection|GLatLng|getMarker|getMarkerCount|getBounds|addMarkers|removeMarker|moveend|getCurrentMapType|call|visible|borderPadding_|height|hide|toggle|width|GPoint|number|fromLatLngToPixel|splice|clearMarkers|typeof|getMapTypes|apply|trigger|ceil|equals'.split('|'),0,{})); self._initAutocomplete('start'); self._initAutocomplete('end'); if (GBrowserIsCompatible()) { var mapTypes = G_DEFAULT_MAP_TYPES; for(var i = 0; i < mapTypes.length; i++) { mapTypes[i].getMinimumResolution = function(latlng) { return 4; }; } self.map = new GMap2(document.getElementById("map")); self.map.setUIToDefault(); var zoom = 7; self.gDir = new GDirections(); self.map.setCenter(new GLatLng(self.coord.x, self.coord.y), zoom); self.manager = new MarkerManager(self.map); self._addListeners(); self.loadUrl(); } }, /** * Обработка хэша страницы, как постоянного URL * * @params string * @return void */ loadUrl: function(url) { var self = this; if(typeof url != "undefined") { location.href = url; } var hash = location.hash.match(/^\#(([0-9]+\:?){4,7})$/); if(location.hash.length > 0 && hash !== null) { try { hash = hash[1].split(':'); jQuery('#road_start_point').attr('hidden', hash[0]); var n = hash.length - 3; if(hash.length > 4) { for(i = 1; i < n; i++) { self.addPoint(hash[i]); } } jQuery('#road_end_point').attr('hidden', hash[n++]); var _temp = hash[n].substr(0, 4) + "-" + hash[n].substr(4, 2) + "-"; _temp+= hash[n].substr(6, 2) + "/" + hash[n].substr(8, 2) + ":"; _temp+= hash[n].substr(10, 2); _temp = _temp.split('/'); jQuery('#road_settings_form #data').attr('value', _temp[0]); jQuery('#road_settings_form #time').attr('value', _temp[1]); jQuery('#road_settings_form #speed').attr('value', hash[++n]); } finally { self.render(true); } } else { if(jQuery('#road_start_point').val().length && jQuery('#road_end_point').val().length) self.render(true); } }, /** * Добавление промежуточной точки * * @params string * @params boolean * @return void */ addPoint: function(value, real_value) { var count = jQuery('.middlepoints').length; if(count < 3) { var elem = jQuery('').addClass('middlepoints'); var attr = (typeof real_value !== "undefined") ? "value" : "hidden"; jQuery('').appendTo(elem); jQuery('').click(GRoads.removePoint).appendTo(elem); jQuery('
').appendTo(elem); jQuery('').append(elem).insertBefore("#road_last_point"); if(count >= 2) jQuery("#road_add_point").hide(); GRoads._initAutocomplete('middle' + count); } }, /** * Удаление пормежуточной точки * * @return void */ removePoint: function() { jQuery(this).parent().parent().remove(); jQuery("#road_add_point").show(); }, /** * Округление числа до тысячных * * @private * @param float * @return float */ _round: function(num, pow) { return parseInt(num * Math.pow(10, pow)) / Math.pow(10, pow); }, /** * Установка обработчиков событий * * @private * @return void */ _addListeners: function (){ var self = this; jQuery("#road_render").removeAttr('disabled'); Calendar.setup({ ifFormat: "%Y-%m-%d", button: "but_cal", inputField: "data", singleClick: true, showsTime: false, step: 1 }); jQuery("#road_render").bind("click", function() { jQuery("#road_render").attr('disabled', 'disabled'); self.render(true); }); GEvent.addListener(self.gDir, "error", function() { self.error(self.gDir.getStatus().code); }); jQuery('#road_add_point').bind('click', function() { self.addPoint(); return false; }); jQuery('.removable').bind('keydown', function() { jQuery(this).removeAttr('hidden'); }); jQuery('#quick_links a').bind('click', function() { jQuery("#road_settings_form input.road_point[type=text]").removeAttr('hidden'); self.loadUrl(jQuery(this).attr('href')); }); jQuery('#roads_text_info a.print').bind('click', function() { var print = window.open("", "roads_print", "titlebar=1,menubar=1,status=1,width=800,height=600"); print.document.write('Meteoprog'); print.document.write(''); print.document.write('
Meteoprog
www.meteoprog.ua
' + location.href + '
' + jQuery('#roads_text_info').html() + '
'); return false; }); }, /** * Является ли число координатой * * @private * @param float * @return boolean */ _isCoord: function (x) { if(typeof x == "undefined") { _return = false; } else { x = x.match(/([-]{0,1}[0-9]{1,4}(\.[0-9]{1,9})?)/); _return = (x === null) ? false : x[1]; } return _return; }, /** * Выводит информацию о маршруте * * @private * @return void */ _loadInfo: function(way) { var self = this; var t = ''; var d = self._calcDuration(way.distance, way.speed); t+= (d.days === 0) ? "" : d.days + " д. "; t+= (d.hours === 0) ? "" : d.hours + " ч. "; t+= (d.minutes === 0) ? "" : d.minutes + " м."; jQuery("#road_info #length").html(parseInt(way.distance / 1000) + " км."); jQuery("#road_info #time").html(t); jQuery("#road_info #speed").html(way.speed + " км/ч"); jQuery("#road_info").slideDown(); }, /** * Загрузка данных о погоде * * @private * @param object * @return void */ _loadData: function (way) { var self = this; var points = self._serialize(way.points); var zoom = self.map.getZoom(); var start_date = jQuery('#road_settings_form #data').attr('value'); var params = []; if(!self.cached) { params.push("points=" + points); params.push("core=" + self.hash); } else { params.push("cacheid=" + self.crc32(self.hash)); } params.push("lang=" + self.lang); params.push("zoom=" + zoom); params.push("start_date=" + start_date); params.push("start_time=" + self._getTime()) params.push("speed=" + self._getSpeed()); params.push("vertex_count=" + self._last_overlay.length); params.push("type=roads"); new Ajax.Request('/' + self.lang + '/roads/json/' + Math.random(), { 'method': 'post', 'postBody': params.join("&"), 'onSuccess': function(data) { var json = data.responseJSON; if(json.status == "success") { self._points = json.points; self._brand = json.brand; self._redrawPoints(json, zoom); self.fetchTable(json, way); } else { self.error(json.code); } jQuery('#titlemap .title h3').css('background', ''); } }); jQuery("#road_render").removeAttr('disabled'); }, /** * Перерисовка маркеров на карте * * @private * @params object * @params int * @return void */ _redrawPoints: function(json, zoom) { var self = this; zoom = zoom || self.map.getZoom(); var data = json.points; var dataWOG = json.brand; self.manager.clearMarkers(); var container = []; var last = current = new GLatLng(0, 0); // хм... var last_key = false; jQuery.each(data, function(k, _data) { last_key = k; current = new GLatLng(_data.x, _data.y); if(current.distanceFrom(last) > (self._getZoomK() * 1000)) { //roma сколько точек отображается сколько и тут //alert(current.distanceFrom(last)+' '+(self._getZoomK() * 1000)) container.push(self._displayPoint(_data)); last = current; } }); var _t = (last.distanceFrom(new GLatLng(data[last_key].x, data[last_key].y)) > (self._getZoomK() * 1000)) ? 0 : 1; container[container.length - _t] = self._displayPoint(data[last_key]); var containerWOG = []; jQuery.each(dataWOG, function(k, _data) { containerWOG.push(self._displayPointWOG(_data)); }); self.manager.addMarkers(containerWOG, zoom); self.manager.addMarkers(container, zoom); self.manager.refresh(); }, _displayPointWOG: function(_data) { var point = new GLatLng(_data.x, _data.y); var icon = new GIcon(); icon.image = "/images/roads/wog.gif"; icon.iconAnchor = new GPoint(15, 46); //new GPoint(55, 46); icon.iconSize = new GSize(28, 25); var marker = new GMarker(point, {icon: icon,zIndexProcess: changeZIndex}); return marker; }, /** * Генерация маркера * * @private * @params object * @return GMarker */ _displayPoint: function(_data) { var point = new GLatLng(_data.x, _data.y); var icon = new GIcon(); icon.image = "/pictures/markers/" + _data.link; icon.iconAnchor = new GPoint(20, _data.sy); icon.iconSize = new GSize(_data.sx, _data.sy); var marker = new GMarker(point, {icon: icon }); marker.url = '/' + curlang + '/weather/' + _data.url; GEvent.addListener(marker, "click", function() { window.open(this.url, '', ''); }); return marker; }, /** * Сериализация параметров для отправки GET-запроса * * @private * @param object * @return string */ _serialize: function(points) { var data = []; var self = this; points.each(function(point) { data.push([self._round(point.x, 3), self._round(point.y, 3), point.t].join(",")); }); return data.join(";"); }, /** * Инициализация автокомплита для точек * * @private * @param string * @return object */ _initAutocomplete: function(id) { return new Ajax.Autocompleter( 'road_' + id + '_point', 'road_' + id + '_autocomplete', '/' + curlang + '/search/cities/', { frequency: 0.1, afterUpdateElement: function(text, li) { jQuery('#road_' + id + '_point').attr('hidden', li.id); } } ); }, /** * Отрисовка * * @params boolean * @return void */ render: function(zoomed) { var self = this; jQuery("#road_error").hide(); jQuery('#roads_text_info').hide(); var validation = []; validation.push(self._isValid('#road_start_point', GRoads.ER_FIRST_CITY_NOT_SET)); validation.push(self._isValid('#road_end_point', GRoads.ER_SECOND_CITY_NOT_SET)); if(validation[0] && validation[1]) { var coords = []; var params = []; var isNames = false; jQuery("#road_start_point").css("background-color", ""); jQuery("#road_end_point").css("background-color", ""); GEvent.clearListeners(self.gDir, "load"); //после загрузки направления GEvent.addListener(self.gDir, "load", function() { jQuery('#titlemap .title').slideDown(); self.map.clearOverlays(); self._last_overlay = self.gDir.getPolyline(); self.map.addOverlay(self._last_overlay); self.way.points = []; self.way.speed = self._getSpeed(); self.way.distance = self.gDir.getDistance().meters; //The following example uses getBounds() to return the current viewport //Верний левый и правий нижний угол коорд долг и шир var bounds = self.gDir.getBounds(); if(!zoomed) { bounds = null; } if(bounds !== null) { var zoom = self.map.getBoundsZoomLevel(bounds); self._fake_zoom = true; self.map.setZoom(zoom); } var points = self._last_overlay;//.g; // undocument feature var _length = self._calcDuration(self.way.distance, self.way.speed, true); var gpoint=[]; for (var i=0; i< self.gDir.getPolyline().getVertexCount(); i++) { gpoint[i] = self.gDir.getPolyline().getVertex(i); } points = gpoint; for(var i = j = distance = 0; i < points.length; i++) { points[i].distance = 0; j = i == 0 ? 0 : i - 1; distance = points[j].distanceFrom(points[i]); points[i].distance = self._round(points[j].distance, 5) + self._round(distance / 1000, 5); self.way.points.push({ x: points[i].y, y: points[i].x, t: Math.round(points[i].distance / self.way.speed * 60 * 60) }); } self._loadInfo(self.way); if(self._validDate()) { self._loadData(self.way); } else { self.error(self.ER_WRONG_DATE); } if(bounds !== null) { var center = bounds.getCenter(); self.map.panTo(center); } }); var points = []; jQuery("#road_settings_form input.road_point[type=text]").each(function(i, val) { var elem = jQuery(val); if(elem.attr('hidden') && elem.attr('hidden').length > 0) { params.push(elem.attr('id') + "=" + elem.attr('hidden')); points.push(elem.attr('id')); elem.removeAttr('hidden'); } else if(elem.attr('value').length > 0) { params.push(elem.attr('id') + "=" + elem.attr('value')); points.push(elem.attr('id')); } }); params.push("points=" + points.join()); params.push("speed=" + self._getSpeed()); params.push("lang=" + self.lang); params.push("type=roads_list"); new Ajax.Request('/' + self.lang + '/roads/json/' + Math.random(), { 'method': 'post', 'postBody': params.join("&"), 'onSuccess': function(data) { var _ajax_data = data.responseJSON; self.hash = []; var url = []; var names = []; if(_ajax_data.state === "success") { jQuery('#road_start_point').attr('value', _ajax_data.coords[0].name); var n = _ajax_data.coords.length - 2; if(_ajax_data.coords.length > 2) { for(i = 0; i < n; i++) { jQuery('#road_middle' + i + '_point').attr('value', _ajax_data.coords[i + 1].name); } } jQuery('#road_end_point').attr('value', _ajax_data.coords[++n].name); _ajax_data.coords.each(function(item) { coords.push(self._validate(item.x, item.y)); self.hash.push(item.x + ":" + item.y); url.push(item.id); names.push(item.name); }); self.hash.push(self._getSpeed()); self.cached = (_ajax_data.cached || false); self.hash = self.hash.join(); location.hash = self.genShortUrl(url); jQuery('input.direct_link').attr('value', location.href); var title = jQuery('#titlemap .title h3').html("Маршрут " + names.join(' - ')); jQuery('#roads_text_info h2').html("Текстовый прогноз по маршруту " + names.join(' - ')); jQuery('#titlemap .title h3').css('background', 'transparent url(/images/loading.gif) no-repeat 50% 50%'); } else { coords = false; self.error(_ajax_data.code); } self.gDir.loadFromWaypoints(coords, { preserveViewport: false, getPolyline: true, locale: self.lang }); } }); GEvent.clearListeners(self.map, "zoomend"); GEvent.addListener(self.map, "zoomend", function() { !self._fake_zoom ? self._redrawPoints({points:self._points,brand:self._brand}) : self._fake_zoom = false; }); } }, /** * Проверка валидности даты * * @private * @return boolean */ _validDate: function() { var date = jQuery('#road_settings_form #data').attr('value').replace(/\-/g, '/'); var d1 = parseInt((new Date(date).valueOf())); var d2 = d1+(60 * 60 * 24 * 7 * 1000); valid = d1< (d1+d2); //alert(d1+' date2:'+d2+' valid:'+valid); //valid = valid && (d1 > d2); return valid; }, /** * Генерация короткого хэша адреса * * @param string * @return string */ genShortUrl: function(str) { var self = this; str.push(jQuery('#road_settings_form #data').attr('value').replace(/\-/g, '') + self._getTime().replace(/\:/g, '')); str.push(self._getSpeed()); return str.join(':'); }, /** * Валидация координат * * @private * @param string * @param string * @return object */ _validate: function(x, y) { var _x = this._isCoord(x.toString()); var _y = this._isCoord(y.toString()); return (_x && _y) ? new GLatLng(_x, _y) : null; }, /** * Обработка ошибок * * @param int * @return void */ error: function(code) { switch(code) { case G_GEO_BAD_REQUEST: case G_GEO_SERVER_ERROR: case G_GEO_MISSING_QUERY: case G_GEO_UNKNOWN_ADDRESS: case G_GEO_UNAVAILABLE_ADDRESS: case G_GEO_UNKNOWN_DIRECTIONS: case G_GEO_BAD_KEY: case G_GEO_TOO_MANY_QUERIES: status = "Запрос маршрутов не удалось выполнить успешно."; break; case GRoads.ER_FIRST_CITY_NOT_SET: status = "Не указана первая пара координат."; jQuery("#road_start_point").css("background-color", "#faa"); break; case GRoads.ER_SECOND_CITY_NOT_SET: status = "Не указана вторая пара координат."; jQuery("#road_end_point").css("background-color", "#faa"); break; case GRoads.ER_FIRST_CITY_NOT_FOUND: status = "Указаная точка не найдена в базе данных."; jQuery("#road_start_point").css("background-color", "#faa"); break; case GRoads.ER_SECOND_CITY_NOT_FOUND: status = "Указаная точка не найдена в базе данных."; jQuery("#road_end_point").css("background-color", "#faa"); break; case GRoads.ER_CITY_NOT_FOUND: alert("Exception:\r\nGRoads.ER_CITY_NOT_FOUND throwed"); break; case GRoads.ER_WRONG_DATE: status = "Прогноз погоды доступен только на 7 дней"; break; } jQuery("#road_error").html(status).slideDown(); jQuery("#road_render").removeAttr('disabled'); jQuery('#titlemap .title h3').css('background', ''); }, /** * Узнаём размер маркера для текущего масштаба * * @private * @return float */ _getZoomK: function() { var self = this; var _k = [500, 300, 160, 90, 60, 22, 11, 5.5, 3, 1.5, 0.64, 0.35, 0.18, 0.1, 0.05, 0.03]; var z = self.map.getZoom(); if(z < 4) z = 0; else if(z > 19) z = 15; else z-= 4; return _k[z]; }, /** * Вычисление продолжительности маршрута с учетом скорости * * @private * @param int * @param int * @return object */ _calcDuration: function(len, speed, inSeconds) { inSeconds = inSeconds || false; var time = len / speed; time*= 60 * 60; var d = new Date(time); var data = { "days": (d.getUTCDate() - 1), "hours": d.getUTCHours(), "minutes": d.getUTCMinutes() }; return inSeconds ? d.valueOf() : data; }, /** * Вычисление дистанции между двумя кооринатами * * @private * @param array * @param array * @return float */ _calcDistance: function(start, end) { var R = 6371; // km var dLat = (end.x - start.x).toRad(); var dLon = (end.y - start.y).toRad(); var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(start.x.toRad()) * Math.cos(end.x.toRad()) * Math.sin(dLon / 2) * Math.sin(dLon / 2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return R * c; }, /** * Валидация поля ввода координат * * @private * @param string * @param int * @return bool */ _isValid: function(id, code) { var ret1 = jQuery(id).attr("value").length > 0; var ret2 = jQuery(id).attr("hidden") ? (jQuery(id).attr("hidden").length > 0) : false; var ret = ret1 || ret2; !ret ? this.error(code) : jQuery(id).css("background-color", ""); return ret; }, /** * Заполнение таблицы с погодой * * @param object * @param object * @return void */ fetchTable: function(data, way) { var self = this; var odd = 0; var _length = _current = 0; var _last = false; //data.each(function(_data, i) { var last_key = false; var i=0; jQuery.each(data.points, function(k, _data) { if(i==0) _last = new GLatLng(_data.x, _data.y); last_key = k; _current = new GLatLng(_data.x, _data.y); _length+= self._round(_current.distanceFrom(_last) / 1000, 5); _last = _current; data.points[k]._length = _length; i++; }); //Коефициент последний поделить на предпоследний, но зачем???????? var K = (way.distance / 1000) / data.points[last_key]._length; jQuery('#road_weather_table tbody').empty(); jQuery.each(data.wog_weather, function(k, _w) { if(_w.it==2) { var _data = data.brand[_w.sec]; var address = _data.address; var phone = (_data.phone == null)? '':'телефон: '+_data.phone; var service = new Array(); if(_data.m100 == 1) service[0] = ''; if(_data.m95 == 1) service[1] = ''; if(_data.a92 == 1) service[2] = ''; if(_data.a80 == 1) service[3] = ''; if(_data.dp == 1) service[4] = ''; if(_data.gas == 1) service[5] = ''; if(_data.bar == 1) service[6] = ''; if(_data.shop == 1) service[7] = ''; if(_data.wash == 1) service[8] = ''; if(_data.pidkachka == 1) service[9] = ''; if(_data.wc == 1) service[10] = ''; var service_str = service.join(''); var tpl = '
\
'+address+''+phone+'
\
'+service_str+'
\
'; var tr = jQuery(""); jQuery('') .html(tpl) .appendTo(tr); jQuery('#road_weather_table tbody').append(tr); } if(_w.it==1) { var _data = data.points[_w.sec]; var tr = jQuery("").addClass(odd % 2 ? 'odd' : 'even'); var _tmp = []; // Пункт и время прибытия var date = new Date(_data.date.replace(/T{1}/, ' ').replace(/\-/g, '/')); var _date = self._hourRound(date.getDate()) + '/' + self._hourRound(date.getMonth() + 1) + '/' + date.getFullYear() + " "; _date+= self._hourRound(date.getHours()) + ":" + self._hourRound(date.getMinutes()); _data.name = "" + _data.name + ""; jQuery("") .attr("width", "20%") .html([_data.name, _date].join("
")) .appendTo(tr); // Осадки, облачность, температура var time = self._hourRound(date.getHours()); var daytime = (time > 8 && time < 18) ? "day" : "night"; jQuery("") .attr("width", "14%") .html(" " + _data.temp + " °C") .prepend(jQuery('').attr('src', "/images/roads/images_" + daytime + "/weather_" + _data.sun + ".png")) .addClass('temperature') .addClass(_data.temp > 0 ? 'hi' : 'lo') .appendTo(tr); // Обратите внимание jQuery("") .attr("width", "15%") .addClass('attention') .attr("align", "center") .html(self._getAttention(_data)) .appendTo(tr); // Осадки jQuery("") .attr("width", "8%") .attr("align", "center") .html(self._round(parseFloat(_data.rain), 1) + " мм") .appendTo(tr); // Давление jQuery("") .attr("width", "12%") .attr("align", "center") .css('font-weight', 'bold') .html(_data.pressure + " мм рт.ст.") .appendTo(tr); // Ветер jQuery("") .attr("width", "12%") .attr("align", "center") .html(Math.round(_data.wind[0]) + " м/с, ") .append(jQuery('').attr('src', "/images/roads/wind/" + _data.wind[2] + ".gif")) .append(jQuery('').html(" " + _data.wind[1])) .appendTo(tr); // Влажность jQuery("") .attr("width", "8%") .attr("align", "center") .html(_data.humidity + "%") .appendTo(tr); // Длина и время пути _tmp = GRoads._calcDuration(_data._length * 1000 * K, way.speed); _tmp = (_tmp.days * 24 + _tmp.hours) + ":" + self._hourRound(_tmp.minutes); jQuery("") .attr("width", "10%") .attr("align", "right") .html('' + Math.round(_data._length * K) + " км
" + _tmp + " часа") .appendTo(tr); jQuery('#road_weather_table tbody').append(tr); odd++; } }); if(jQuery(data).length > 0) { jQuery('#roads_text_info').show(); } jQuery('#roads_main_table').css('border-bottom', '2px solid #fe4a15'); }, /** * Создание предупреждения в таблице * * @private * @params object * @return string */ _getAttention: function(data) { var att = []; if(data.wind[0] > 6) { att.push("Ветер " + data.wind[0] + " м/с"); } if(parseFloat(data.rain) > 2) { att.push("Сильный дождь"); } return att.join("
"); }, /** * Выбрать скорость из формы * * @return int */ _getSpeed: function() { var speed = parseInt(jQuery('#road_settings_form #speed').attr('value')); return (isNaN(speed) || (speed < 10) || (speed > 320)) ? 70 : Math.abs(speed); }, /** * Выбрать время из формы * * @return string */ _getTime: function() { var time = jQuery('#road_settings_form #time').attr('value'); var cond = [] cond.push(time.match(/^[0-9]{1,2}\:[0-9]{1,2}$/)); time = time.split(':'); cond.push((time[0] <= 24) && (time[0] >= 0)); cond.push((time[1] <= 60) && (time[1] >= 0)); return (cond[0] && cond[1] && cond[2]) ? time.join(":") : "12:00"; }, /** * Форматирование чисел * * @private * @params int * @return string */ _hourRound: function(i) { return ((i < 10) ? ('0' + i) : i); }, /** * Обсчет контрольной суммы * * @see http://www.webtoolkit.info/javascript-crc32.html * @param string * @return string */ crc32: function(str) { function utf8_encode(argString) { var string = (argString+''); var utftext = ""; var start, end; var stringl = 0; start = end = 0; stringl = string.length; for(var n = 0; n < stringl; n++) { var c1 = string.charCodeAt(n); var enc = null; if(c1 < 128) { end++; } else if(c1 > 127 && c1 < 2048) { enc = String.fromCharCode((c1 >> 6) | 192); enc+= String.fromCharCode((c1 & 63) | 128); } else { enc = String.fromCharCode((c1 >> 12) | 224); enc+= String.fromCharCode(((c1 >> 6) & 63) | 128); enc+= String.fromCharCode((c1 & 63) | 128); } if(enc !== null) { if(end > start) { utftext+= string.substring(start, end); } utftext+= enc; start = end = n+1; } } if(end > start) { utftext+= string.substring(start, string.length); } return utftext; } str = utf8_encode(str); var table = "00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 "; table+= "0EDB8832 79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 "; table+= "1DB71064 6AB020F2 F3B97148 84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 "; table+= "136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F 63066CD9 FA0F3D63 8D080DF5 "; table+= "3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD A50AB56B "; table+= "35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 "; table+= "26D930AC 51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F "; table+= "2802B89E 5F058808 C60CD9B2 B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D "; table+= "76DC4190 01DB7106 98D220BC EFD5102A 71B18589 06B6B51F 9FBFE4A5 E8B8D433 "; table+= "7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 E6635C01 "; table+= "6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 "; table+= "65B0D9C6 12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 "; table+= "4DB26158 3AB551CE A3BC0074 D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB "; table+= "4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 33031DE5 AA0A4C5F DD0D7CC9 "; table+= "5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 CE61E49F "; table+= "5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD "; table+= "EDB88320 9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 "; table+= "E3630B12 94643B84 0D6D6A3E 7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 "; table+= "F00F9344 8708A3D2 1E01F268 6906C2FE F762575D 806567CB 196C3671 6E6B06E7 "; table+= "FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 60B08ED5 "; table+= "D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B "; table+= "D80D2BDA AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 "; table+= "CB61B38C BC66831A 256FD2A0 5268E236 CC0C7795 BB0B4703 220216B9 5505262F "; table+= "C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 B5D0CF31 2CD99E8B 5BDEAE1D "; table+= "9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 05005713 "; table+= "95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 "; table+= "86D3D2D4 F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 "; table+= "88085AE6 FF0F6A70 66063BCA 11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 "; table+= "A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 D06016F7 4969474D 3E6E77DB "; table+= "AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F 30B5FFE9 "; table+= "BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF "; table+= "B3667A2E C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D"; var crc = 0; var x = 0; var y = 0; crc = crc ^ (-1); for(var i = 0, iTop = str.length; i < iTop; i++) { y = (crc ^ str.charCodeAt(i)) & 0xFF; x = "0x" + table.substr(y * 9, 8); crc = (crc >>> 8) ^ x; } return Math.abs(crc ^ (-1)); } } var changeZIndex = function(marker) { var myNewZIndex = -200000000; return myNewZIndex; };