Skip to content
This repository
Browse code

First shot at making a wrapping, but correctly cutting-off sourceCoor…

…dinate function. Refs #88.
  • Loading branch information...
commit c3dfdb95ef3379e603ce955a84ab8e08b33d4ed3 1 parent a6322ae
Tom MacWright tmcw authored

Showing 3 changed files with 59 additions and 57 deletions. Show diff stats Hide diff stats

  1. +29 28 modestmaps.js
  2. +1 1  modestmaps.min.js
  3. +29 28 src/provider.js
57 modestmaps.js
@@ -718,8 +718,10 @@ var MM = com.modestmaps = {
718 718 // these are limits for available *tiles*
719 719 // panning limits will be different (since you can wrap around columns)
720 720 // but if you put Infinity in here it will screw up sourceCoordinate
721   - tileLimits: [ new MM.Coordinate(0,0,0), // top left outer
722   - new MM.Coordinate(1,1,0).zoomTo(18) ], // bottom right inner
  721 + tileLimits: [
  722 + new MM.Coordinate(0,0,0), // top left outer
  723 + new MM.Coordinate(1,1,0).zoomTo(18) // bottom right inner
  724 + ],
723 725
724 726 getTileUrl: function(coordinate) {
725 727 throw "Abstract method not implemented by subclass.";
@@ -729,9 +731,8 @@ var MM = com.modestmaps = {
729 731 throw "Abstract method not implemented by subclass.";
730 732 },
731 733
732   - releaseTile: function(element) {
733   - // releaseTile is not required
734   - },
  734 + // releaseTile is not required
  735 + releaseTile: function(element) { },
735 736
736 737 // use this to tell MapProvider that tiles only exist between certain zoom levels.
737 738 // should be set separately on Map to restrict interactive zoom/pan ranges
@@ -745,20 +746,24 @@ var MM = com.modestmaps = {
745 746 // ... you should override this function if you change the tile limits
746 747 // ... see enforce-limits in examples for details
747 748 sourceCoordinate: function(coord) {
748   - var TL = this.tileLimits[0].zoomTo(coord.zoom);
749   - var BR = this.tileLimits[1].zoomTo(coord.zoom);
750   - var vSize = BR.row - TL.row;
751   - if (coord.row < 0 || coord.row >= vSize) {
752   - // it's too high or too low:
753   - return null;
  749 + var TL = this.tileLimits[0].zoomTo(coord.zoom),
  750 + BR = this.tileLimits[1].zoomTo(coord.zoom),
  751 + columnSize = Math.pow(2, coord.zoom),
  752 + wrappedColumn;
  753 +
  754 + if (coord.column < 0) {
  755 + wrappedColumn = (coord.column + columnSize) % columnSize;
  756 + } else {
  757 + wrappedColumn = coord.column % columnSize;
754 758 }
755   - var hSize = BR.column - TL.column;
756   - // assume infinite horizontal scrolling
757   - var wrappedColumn = coord.column % hSize;
758   - while (wrappedColumn < 0) {
759   - wrappedColumn += hSize;
  759 +
  760 + if (coord.row < TL.row || coord.row >= BR.row) {
  761 + return null;
  762 + } else if (wrappedColumn < TL.column || wrappedColumn >= BR.column) {
  763 + return null;
  764 + } else {
  765 + return new MM.Coordinate(coord.row, wrappedColumn, coord.zoom);
760 766 }
761   - return new MM.Coordinate(coord.row, wrappedColumn, coord.zoom);
762 767 }
763 768 };
764 769
@@ -786,15 +791,12 @@ var MM = com.modestmaps = {
786 791 *
787 792 */
788 793 MM.TemplatedMapProvider = function(template, subdomains) {
789   - var isQuadKey = false;
790   - if (template.match(/{(Q|quadkey)}/)) {
791   - isQuadKey = true;
792   - // replace Microsoft style substitution strings
793   - template = template
794   - .replace('{subdomains}', '{S}')
795   - .replace('{zoom}', '{Z}')
796   - .replace('{quadkey}', '{Q}');
797   - }
  794 + var isQuadKey = template.match(/{(Q|quadkey)}/);
  795 + // replace Microsoft style substitution strings
  796 + if (isQuadKey) template = template
  797 + .replace('{subdomains}', '{S}')
  798 + .replace('{zoom}', '{Z}')
  799 + .replace('{quadkey}', '{Q}');
798 800
799 801 var hasSubdomains = (subdomains &&
800 802 subdomains.length && template.indexOf("{S}") >= 0);
@@ -838,8 +840,7 @@ var MM = com.modestmaps = {
838 840 },
839 841 getTile: function(coord) {
840 842 return this.getTileUrl(coord);
841   - },
842   - releaseTile: function() { }
  843 + }
843 844 };
844 845
845 846 MM.extend(MM.TemplatedMapProvider, MM.MapProvider);
2  modestmaps.min.js
@@ -11,4 +11,4 @@
11 11 * See CHANGELOG and http://semver.org/ for more details.
12 12 *
13 13 */
14   -var previousMM=MM;if(!com){var com={};if(!com.modestmaps){com.modestmaps={}}}var MM=com.modestmaps={noConflict:function(){MM=previousMM;return this}};(function(b){b.extend=function(e,c){for(var d in c.prototype){if(typeof e.prototype[d]=="undefined"){e.prototype[d]=c.prototype[d]}}return e};b.getFrame=function(){return function(c){(window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(d){window.setTimeout(function(){d(+new Date())},10)})(c)}}();b.transformProperty=(function(e){if(!this.document){return}var d=document.documentElement.style;for(var c=0;c<e.length;c++){if(e[c] in d){return e[c]}}return false})(["transformProperty","WebkitTransform","OTransform","MozTransform","msTransform"]);b.matrixString=function(c){if(c.scale*c.width%1){c.scale+=(1-c.scale*c.width%1)/c.width}if(b._browser.webkit3d){return"matrix3d("+[(c.scale||"1"),"0,0,0,0",(c.scale||"1"),"0,0","0,0,1,0",(c.x+(((c.width*c.scale)-c.width)/2)).toFixed(4),(c.y+(((c.height*c.scale)-c.height)/2)).toFixed(4),0,1].join(",")+")"}else{var d=(b.transformProperty=="MozTransform")?"px":"";return"matrix("+[(c.scale||"1"),0,0,(c.scale||"1"),(c.x+(((c.width*c.scale)-c.width)/2))+d,(c.y+(((c.height*c.scale)-c.height)/2))+d].join(",")+")"}};b._browser=(function(c){return{webkit:("WebKitCSSMatrix" in c),webkit3d:("WebKitCSSMatrix" in c)&&("m11" in new WebKitCSSMatrix())}})(this);b.moveElement=function(e,c){if(b.transformProperty){if(!c.scale){c.scale=1}if(!c.width){c.width=0}if(!c.height){c.height=0}var d=b.matrixString(c);if(e[b.transformProperty]!==d){e.style[b.transformProperty]=e[b.transformProperty]=d}}else{e.style.left=c.x+"px";e.style.top=c.y+"px";if(c.width&&c.height&&c.scale){e.style.width=Math.ceil(c.width*c.scale)+"px";e.style.height=Math.ceil(c.height*c.scale)+"px"}}};b.cancelEvent=function(c){c.cancelBubble=true;c.cancel=true;c.returnValue=false;if(c.stopPropagation){c.stopPropagation()}if(c.preventDefault){c.preventDefault()}return false};b.bind=function(e,f){var g=Array.prototype.slice;var d=Function.prototype.bind;if(e.bind===d&&d){return d.apply(e,g.call(arguments,1))}var c=g.call(arguments,2);return function(){return e.apply(f,c.concat(g.call(arguments)))}};b.addEvent=function(e,d,c){if(e.addEventListener){e.addEventListener(d,c,false);if(d=="mousewheel"){e.addEventListener("DOMMouseScroll",c,false)}}else{if(e.attachEvent){e["e"+d+c]=c;e[d+c]=function(){e["e"+d+c](window.event)};e.attachEvent("on"+d,e[d+c])}}};b.removeEvent=function(e,d,c){if(e.removeEventListener){e.removeEventListener(d,c,false);if(d=="mousewheel"){e.removeEventListener("DOMMouseScroll",c,false)}}else{if(e.detachEvent){e.detachEvent("on"+d,e[d+c]);e[d+c]=null}}};b.getStyle=function(d,c){if(d.currentStyle){return d.currentStyle[c]}else{if(window.getComputedStyle){return document.defaultView.getComputedStyle(d,null).getPropertyValue(c)}}};b.Point=function(c,d){this.x=parseFloat(c);this.y=parseFloat(d)};b.Point.prototype={x:0,y:0,toString:function(){return"("+this.x.toFixed(3)+", "+this.y.toFixed(3)+")"},copy:function(){return new b.Point(this.x,this.y)}};b.Point.distance=function(f,e){var d=(e.x-f.x);var c=(e.y-f.y);return Math.sqrt(d*d+c*c)};b.Point.interpolate=function(g,f,e){var d=g.x+(f.x-g.x)*e;var c=g.y+(f.y-g.y)*e;return new b.Point(d,c)};b.Coordinate=function(e,c,d){this.row=e;this.column=c;this.zoom=d};b.Coordinate.prototype={row:0,column:0,zoom:0,toString:function(){return"("+this.row.toFixed(3)+", "+this.column.toFixed(3)+" @"+this.zoom.toFixed(3)+")"},toKey:function(){return[this.zoom,this.row,this.column].join(",")},copy:function(){return new b.Coordinate(this.row,this.column,this.zoom)},container:function(){return new b.Coordinate(Math.floor(this.row),Math.floor(this.column),Math.floor(this.zoom))},zoomTo:function(c){var d=Math.pow(2,c-this.zoom);return new b.Coordinate(this.row*d,this.column*d,c)},zoomBy:function(d){var c=Math.pow(2,d);return new b.Coordinate(this.row*c,this.column*c,this.zoom+d)},up:function(c){if(c===undefined){c=1}return new b.Coordinate(this.row-c,this.column,this.zoom)},right:function(c){if(c===undefined){c=1}return new b.Coordinate(this.row,this.column+c,this.zoom)},down:function(c){if(c===undefined){c=1}return new b.Coordinate(this.row+c,this.column,this.zoom)},left:function(c){if(c===undefined){c=1}return new b.Coordinate(this.row,this.column-c,this.zoom)}};b.Location=function(c,d){this.lat=parseFloat(c);this.lon=parseFloat(d)};b.Location.prototype={lat:0,lon:0,toString:function(){return"("+this.lat.toFixed(3)+", "+this.lon.toFixed(3)+")"},copy:function(){return new b.Location(this.lat,this.lon)}};b.Location.distance=function(j,i,f){if(!f){f=6378000}var p=Math.PI/180,h=j.lat*p,o=j.lon*p,g=i.lat*p,n=i.lon*p,m=Math.cos(h)*Math.cos(o)*Math.cos(g)*Math.cos(n),l=Math.cos(h)*Math.sin(o)*Math.cos(g)*Math.sin(n),k=Math.sin(h)*Math.sin(g);return Math.acos(m+l+k)*f};b.Location.interpolate=function(j,h,n){if(j.lat===h.lat&&j.lon===h.lon){return new b.Location(j.lat,j.lon)}var t=Math.PI/180,l=j.lat*t,o=j.lon*t,k=h.lat*t,m=h.lon*t;var p=2*Math.asin(Math.sqrt(Math.pow(Math.sin((l-k)/2),2)+Math.cos(l)*Math.cos(k)*Math.pow(Math.sin((o-m)/2),2)));var u=Math.atan2(Math.sin(o-m)*Math.cos(k),Math.cos(l)*Math.sin(k)-Math.sin(l)*Math.cos(k)*Math.cos(o-m))/-(Math.PI/180);u=u<0?360+u:u;var g=Math.sin((1-n)*p)/Math.sin(p);var c=Math.sin(n*p)/Math.sin(p);var s=g*Math.cos(l)*Math.cos(o)+c*Math.cos(k)*Math.cos(m);var r=g*Math.cos(l)*Math.sin(o)+c*Math.cos(k)*Math.sin(m);var q=g*Math.sin(l)+c*Math.sin(k);var e=Math.atan2(q,Math.sqrt(Math.pow(s,2)+Math.pow(r,2)));var i=Math.atan2(r,s);return new b.Location(e/t,i/t)};b.Extent=function(h,d,g,f){if(arguments[0] instanceof b.Location){var e=arguments[0];h=e.lat;d=e.lon}if(arguments[1] instanceof b.Location){var c=arguments[1];g=c.lat;f=c.lon}if(isNaN(g)){g=h}if(isNaN(f)){f=d}this.north=Math.max(h,g);this.south=Math.min(h,g);this.east=Math.max(f,d);this.west=Math.min(f,d)};b.Extent.prototype={north:0,south:0,east:0,west:0,copy:function(){return new b.Extent(this.north,this.west,this.south,this.east)},toString:function(c){if(isNaN(c)){c=3}return[this.north.toFixed(c),this.west.toFixed(c),this.south.toFixed(c),this.east.toFixed(c)].join(", ")},northWest:function(){return new b.Location(this.north,this.west)},southEast:function(){return new b.Location(this.south,this.east)},northEast:function(){return new b.Location(this.north,this.east)},southWest:function(){return new b.Location(this.south,this.west)},center:function(){return new b.Location(this.south+(this.north-this.south)/2,this.east+(this.west-this.east)/2)},encloseLocation:function(c){if(c.lat>this.north){this.north=c.lat}if(c.lat<this.south){this.south=c.lat}if(c.lon>this.east){this.east=c.lon}if(c.lon<this.west){this.west=c.lon}},encloseLocations:function(d){var c=d.length;for(var e=0;e<c;e++){this.encloseLocation(d[e])}},setFromLocations:function(d){var c=d.length,f=d[0];this.north=this.south=f.lat;this.east=this.west=f.lon;for(var e=1;e<c;e++){this.encloseLocation(d[e])}},encloseExtent:function(c){if(c.north>this.north){this.north=c.north}if(c.south<this.south){this.south=c.south}if(c.east>this.east){this.east=c.east}if(c.west<this.west){this.west=c.west}},containsLocation:function(c){return c.lat>=this.south&&c.lat<=this.north&&c.lon>=this.west&&c.lon<=this.east},toArray:function(){return[this.northWest(),this.southEast()]}};b.Extent.fromString=function(d){var c=d.split(/\s*,\s*/);if(c.length!=4){throw"Invalid extent string (expecting 4 comma-separated numbers)"}return new b.Extent(parseFloat(c[0]),parseFloat(c[1]),parseFloat(c[2]),parseFloat(c[3]))};b.Extent.fromArray=function(c){var d=new b.Extent();d.setFromLocations(c);return d};b.Transformation=function(e,g,c,d,f,h){this.ax=e;this.bx=g;this.cx=c;this.ay=d;this.by=f;this.cy=h};b.Transformation.prototype={ax:0,bx:0,cx:0,ay:0,by:0,cy:0,transform:function(c){return new b.Point(this.ax*c.x+this.bx*c.y+this.cx,this.ay*c.x+this.by*c.y+this.cy)},untransform:function(c){return new b.Point((c.x*this.by-c.y*this.bx-this.cx*this.by+this.cy*this.bx)/(this.ax*this.by-this.ay*this.bx),(c.x*this.ay-c.y*this.ax-this.cx*this.ay+this.cy*this.ax)/(this.bx*this.ay-this.by*this.ax))}};b.deriveTransformation=function(m,l,g,f,c,p,i,h,e,d,o,n){var k=b.linearSolution(m,l,g,c,p,i,e,d,o);var j=b.linearSolution(m,l,f,c,p,h,e,d,n);return new b.Transformation(k[0],k[1],k[2],j[0],j[1],j[2])};b.linearSolution=function(f,o,i,e,n,h,d,m,g){f=parseFloat(f);o=parseFloat(o);i=parseFloat(i);e=parseFloat(e);n=parseFloat(n);h=parseFloat(h);d=parseFloat(d);m=parseFloat(m);g=parseFloat(g);var l=(((h-g)*(o-n))-((i-h)*(n-m)))/(((e-d)*(o-n))-((f-e)*(n-m)));var k=(((h-g)*(f-e))-((i-h)*(e-d)))/(((n-m)*(f-e))-((o-n)*(e-d)));var j=i-(f*l)-(o*k);return[l,k,j]};b.Projection=function(d,c){if(!c){c=new b.Transformation(1,0,0,0,1,0)}this.zoom=d;this.transformation=c};b.Projection.prototype={zoom:0,transformation:null,rawProject:function(c){throw"Abstract method not implemented by subclass."},rawUnproject:function(c){throw"Abstract method not implemented by subclass."},project:function(c){c=this.rawProject(c);if(this.transformation){c=this.transformation.transform(c)}return c},unproject:function(c){if(this.transformation){c=this.transformation.untransform(c)}c=this.rawUnproject(c);return c},locationCoordinate:function(d){var c=new b.Point(Math.PI*d.lon/180,Math.PI*d.lat/180);c=this.project(c);return new b.Coordinate(c.y,c.x,this.zoom)},coordinateLocation:function(d){d=d.zoomTo(this.zoom);var c=new b.Point(d.column,d.row);c=this.unproject(c);return new b.Location(180*c.y/Math.PI,180*c.x/Math.PI)}};b.LinearProjection=function(d,c){b.Projection.call(this,d,c)};b.LinearProjection.prototype={rawProject:function(c){return new b.Point(c.x,c.y)},rawUnproject:function(c){return new b.Point(c.x,c.y)}};b.extend(b.LinearProjection,b.Projection);b.MercatorProjection=function(d,c){b.Projection.call(this,d,c)};b.MercatorProjection.prototype={rawProject:function(c){return new b.Point(c.x,Math.log(Math.tan(0.25*Math.PI+0.5*c.y)))},rawUnproject:function(c){return new b.Point(c.x,2*Math.atan(Math.pow(Math.E,c.y))-0.5*Math.PI)}};b.extend(b.MercatorProjection,b.Projection);b.MapProvider=function(c){if(c){this.getTile=c}};b.MapProvider.prototype={tileLimits:[new b.Coordinate(0,0,0),new b.Coordinate(1,1,0).zoomTo(18)],getTileUrl:function(c){throw"Abstract method not implemented by subclass."},getTile:function(c){throw"Abstract method not implemented by subclass."},releaseTile:function(c){},setZoomRange:function(d,c){this.tileLimits[0]=this.tileLimits[0].zoomTo(d);this.tileLimits[1]=this.tileLimits[1].zoomTo(c)},sourceCoordinate:function(h){var c=this.tileLimits[0].zoomTo(h.zoom);var e=this.tileLimits[1].zoomTo(h.zoom);var d=e.row-c.row;if(h.row<0||h.row>=d){return null}var g=e.column-c.column;var f=h.column%g;while(f<0){f+=g}return new b.Coordinate(h.row,f,h.zoom)}};b.TemplatedMapProvider=function(e,c){var f=false;if(e.match(/{(Q|quadkey)}/)){f=true;e=e.replace("{subdomains}","{S}").replace("{zoom}","{Z}").replace("{quadkey}","{Q}")}var d=(c&&c.length&&e.indexOf("{S}")>=0);var g=function(k){var j=this.sourceCoordinate(k);if(!j){return null}var i=e;if(d){var h=parseInt(j.zoom+j.row+j.column,10)%c.length;i=i.replace("{S}",c[h])}if(f){return i.replace("{Z}",j.zoom.toFixed(0)).replace("{Q}",this.quadKey(j.row,j.column,j.zoom))}else{return i.replace("{Z}",j.zoom.toFixed(0)).replace("{X}",j.column.toFixed(0)).replace("{Y}",j.row.toFixed(0))}};b.MapProvider.call(this,g)};b.TemplatedMapProvider.prototype={quadKey:function(g,e,f){var d="";for(var c=1;c<=f;c++){d+=(((g>>f-c)&1)<<1)|((e>>f-c)&1)}return d||"0"},getTile:function(c){return this.getTileUrl(c)},releaseTile:function(){}};b.extend(b.TemplatedMapProvider,b.MapProvider);b.TemplatedLayer=function(d,c){return new b.Layer(new b.TemplatedMapProvider(d,c))};b.getMousePoint=function(g,f){var c=new b.Point(g.clientX,g.clientY);c.x+=document.body.scrollLeft+document.documentElement.scrollLeft;c.y+=document.body.scrollTop+document.documentElement.scrollTop;for(var d=f.parent;d;d=d.offsetParent){c.x-=d.offsetLeft;c.y-=d.offsetTop}return c};b.MouseWheelHandler=function(d,c){if(d){this.init(d,c)}else{if(arguments.length>1){this.precise=c?true:false}}};b.MouseWheelHandler.prototype={precise:false,init:function(d){this.map=d;this._mouseWheel=b.bind(this.mouseWheel,this);this._zoomDiv=document.body.appendChild(document.createElement("div"));this._zoomDiv.style.cssText="visibility:hidden;top:0;height:0;width:0;overflow-y:scroll";var c=this._zoomDiv.appendChild(document.createElement("div"));c.style.height="2000px";b.addEvent(d.parent,"mousewheel",this._mouseWheel)},remove:function(){b.removeEvent(this.map.parent,"mousewheel",this._mouseWheel);this._zoomDiv.parentNode.removeChild(this._zoomDiv)},mouseWheel:function(g){var h=0;this.prevTime=this.prevTime||new Date().getTime();try{this._zoomDiv.scrollTop=1000;this._zoomDiv.dispatchEvent(g);h=1000-this._zoomDiv.scrollTop}catch(d){h=g.wheelDelta||(-g.detail*5)}var f=new Date().getTime()-this.prevTime;if(Math.abs(h)>0&&(f>200)&&!this.precise){var c=b.getMousePoint(g,this.map);this.map.zoomByAbout(h>0?1:-1,c);this.prevTime=new Date().getTime()}else{if(this.precise){var c=b.getMousePoint(g,this.map);this.map.zoomByAbout(h*0.001,c)}}return b.cancelEvent(g)}};b.DoubleClickHandler=function(c){if(c!==undefined){this.init(c)}};b.DoubleClickHandler.prototype={init:function(c){this.map=c;this._doubleClick=b.bind(this.doubleClick,this);b.addEvent(c.parent,"dblclick",this._doubleClick)},remove:function(){b.removeEvent(this.map.parent,"dblclick",this._doubleClick)},doubleClick:function(d){var c=b.getMousePoint(d,this.map);this.map.zoomByAbout(d.shiftKey?-1:1,c);return b.cancelEvent(d)}};b.DragHandler=function(c){if(c!==undefined){this.init(c)}};b.DragHandler.prototype={init:function(c){this.map=c;this._mouseDown=b.bind(this.mouseDown,this);b.addEvent(c.parent,"mousedown",this._mouseDown)},remove:function(){b.removeEvent(this.map.parent,"mousedown",this._mouseDown)},mouseDown:function(c){b.addEvent(document,"mouseup",this._mouseUp=b.bind(this.mouseUp,this));b.addEvent(document,"mousemove",this._mouseMove=b.bind(this.mouseMove,this));this.prevMouse=new b.Point(c.clientX,c.clientY);this.map.parent.style.cursor="move";return b.cancelEvent(c)},mouseMove:function(c){if(this.prevMouse){this.map.panBy(c.clientX-this.prevMouse.x,c.clientY-this.prevMouse.y);this.prevMouse.x=c.clientX;this.prevMouse.y=c.clientY;this.prevMouse.t=+new Date()}return b.cancelEvent(c)},mouseUp:function(c){b.removeEvent(document,"mouseup",this._mouseUp);b.removeEvent(document,"mousemove",this._mouseMove);this.prevMouse=null;this.map.parent.style.cursor="";return b.cancelEvent(c)}};b.MouseHandler=function(c){if(c!==undefined){this.init(c)}};b.MouseHandler.prototype={init:function(c){this.map=c;this.handlers=[new b.DragHandler(c),new b.DoubleClickHandler(c),new b.MouseWheelHandler(c)]},remove:function(){for(var c=0;c<this.handlers.length;c++){this.handlers[c].remove()}}};var a=(function(){var c=window.documentMode;return("onhashchange" in window)&&(c===undefined||c>7)})();b.Hash=function(c){this.onMapMove=b.bind(this.onMapMove,this);this.onHashChange=b.bind(this.onHashChange,this);if(c){this.init(c)}};b.Hash.prototype={map:null,lastHash:null,parseHash:function(f){var c=f.split("/");if(c.length==3){var d=parseInt(c[0],10),e=parseFloat(c[1]),g=parseFloat(c[2]);if(isNaN(d)||isNaN(e)||isNaN(g)){return false}else{return{center:new b.Location(e,g),zoom:d}}}else{return false}},formatHash:function(f){var c=f.getCenter(),e=f.getZoom(),d=Math.max(0,Math.ceil(Math.log(e)/Math.LN2));return"#"+[e,c.lat.toFixed(d),c.lon.toFixed(d)].join("/")},init:function(c){this.map=c;this.map.addCallback("drawn",this.onMapMove);this.lastHash=null;this.onHashChange();if(!this.isListening){this.startListening()}},remove:function(){this.map=null;if(this.isListening){this.stopListening()}},onMapMove:function(d){if(this.movingMap||this.map.zoom===0){return false}var c=this.formatHash(d);if(this.lastHash!=c){location.replace(c);this.lastHash=c}},movingMap:false,update:function(){var e=location.hash;if(e===this.lastHash){return}var d=e.substr(1),c=this.parseHash(d);if(c){this.movingMap=true;this.map.setCenterZoom(c.center,c.zoom);this.movingMap=false}else{this.onMapMove(this.map)}},changeDefer:100,changeTimeout:null,onHashChange:function(){if(!this.changeTimeout){var c=this;this.changeTimeout=setTimeout(function(){c.update();c.changeTimeout=null},this.changeDefer)}},isListening:false,hashChangeInterval:null,startListening:function(){if(a){window.addEventListener("hashchange",this.onHashChange,false)}else{clearInterval(this.hashChangeInterval);this.hashChangeInterval=setInterval(this.onHashChange,50)}this.isListening=true},stopListening:function(){if(a){window.removeEventListener("hashchange",this.onHashChange)}else{clearInterval(this.hashChangeInterval)}this.isListening=false}};b.TouchHandler=function(d,c){if(d){this.init(d,c)}};b.TouchHandler.prototype={maxTapTime:250,maxTapDistance:30,maxDoubleTapDelay:350,locations:{},taps:[],wasPinching:false,lastPinchCenter:null,init:function(d,c){this.map=d;c=c||{};if(!this.isTouchable()){return false}this._touchStartMachine=b.bind(this.touchStartMachine,this);this._touchMoveMachine=b.bind(this.touchMoveMachine,this);this._touchEndMachine=b.bind(this.touchEndMachine,this);b.addEvent(d.parent,"touchstart",this._touchStartMachine);b.addEvent(d.parent,"touchmove",this._touchMoveMachine);b.addEvent(d.parent,"touchend",this._touchEndMachine);this.options={};this.options.snapToZoom=c.snapToZoom||true},isTouchable:function(){var c=document.createElement("div");c.setAttribute("ongesturestart","return;");return(typeof c.ongesturestart==="function")},remove:function(){if(!this.isTouchable()){return false}b.removeEvent(this.map.parent,"touchstart",this._touchStartMachine);b.removeEvent(this.map.parent,"touchmove",this._touchMoveMachine);b.removeEvent(this.map.parent,"touchend",this._touchEndMachine)},updateTouches:function(g){for(var f=0;f<g.touches.length;f+=1){var d=g.touches[f];if(d.identifier in this.locations){var c=this.locations[d.identifier];c.x=d.screenX;c.y=d.screenY;c.scale=g.scale}else{this.locations[d.identifier]={scale:g.scale,startPos:{x:d.screenX,y:d.screenY},x:d.screenX,y:d.screenY,time:new Date().getTime()}}}},sameTouch:function(c,d){return(c&&c.touch)&&(d.identifier==c.touch.identifier)},touchStartMachine:function(c){this.updateTouches(c);return b.cancelEvent(c)},touchMoveMachine:function(c){switch(c.touches.length){case 1:this.onPanning(c.touches[0]);break;case 2:this.onPinching(c);break}this.updateTouches(c);return b.cancelEvent(c)},touchEndMachine:function(m){var d=new Date().getTime();if(m.touches.length===0&&this.wasPinching){this.onPinched(this.lastPinchCenter)}for(var k=0;k<m.changedTouches.length;k+=1){var p=m.changedTouches[k],l=this.locations[p.identifier];if(!l||l.wasPinch){continue}var o={x:p.screenX,y:p.screenY},g=d-l.time,f=b.Point.distance(o,l.startPos);if(f>this.maxTapDistance){}else{if(g>this.maxTapTime){o.end=d;o.duration=g;this.onHold(o)}else{o.time=d;this.onTap(o)}}}var n={};for(var h=0;h<m.touches.length;h++){n[m.touches[h].identifier]=true}for(var c in this.locations){if(!(c in n)){delete n[c]}}return b.cancelEvent(m)},onHold:function(c){},onTap:function(c){if(this.taps.length&&(c.time-this.taps[0].time)<this.maxDoubleTapDelay){this.onDoubleTap(c);this.taps=[];return}this.taps=[c]},onDoubleTap:function(d){var f=this.map.getZoom(),g=Math.round(f)+1,c=g-f;var e=new b.Point(d.x,d.y);this.map.zoomByAbout(c,e)},onPanning:function(e){var d={x:e.screenX,y:e.screenY},c=this.locations[e.identifier];this.map.panBy(d.x-c.x,d.y-c.y)},onPinching:function(j){var i=j.touches[0],h=j.touches[1],l=new b.Point(i.screenX,i.screenY),k=new b.Point(h.screenX,h.screenY),f=this.locations[i.identifier],d=this.locations[h.identifier];f.wasPinch=true;d.wasPinch=true;var c=b.Point.interpolate(l,k,0.5);this.map.zoomByAbout(Math.log(j.scale)/Math.LN2-Math.log(f.scale)/Math.LN2,c);var g=b.Point.interpolate(f,d,0.5);this.map.panBy(c.x-g.x,c.y-g.y);this.wasPinching=true;this.lastPinchCenter=c},onPinched:function(c){if(this.options.snapToZoom){var d=this.map.getZoom(),e=Math.round(d);this.map.zoomByAbout(e-d,c)}this.wasPinching=false}};b.CallbackManager=function(c,e){this.owner=c;this.callbacks={};for(var d=0;d<e.length;d++){this.callbacks[e[d]]=[]}};b.CallbackManager.prototype={owner:null,callbacks:null,addCallback:function(c,d){if(typeof(d)=="function"&&this.callbacks[c]){this.callbacks[c].push(d)}},removeCallback:function(f,g){if(typeof(g)=="function"&&this.callbacks[f]){var d=this.callbacks[f],c=d.length;for(var e=0;e<c;e++){if(d[e]===g){d.splice(e,1);break}}}},dispatchCallback:function(f,d){if(this.callbacks[f]){for(var c=0;c<this.callbacks[f].length;c+=1){try{this.callbacks[f][c](this.owner,d)}catch(g){}}}}};b.RequestManager=function(){this.loadingBay=document.createDocumentFragment();this.requestsById={};this.openRequestCount=0;this.maxOpenRequests=4;this.requestQueue=[];this.callbackManager=new b.CallbackManager(this,["requestcomplete","requesterror"])};b.RequestManager.prototype={loadingBay:null,requestsById:null,requestQueue:null,openRequestCount:null,maxOpenRequests:null,callbackManager:null,addCallback:function(c,d){this.callbackManager.addCallback(c,d)},removeCallback:function(c,d){this.callbackManager.removeCallback(c,d)},dispatchCallback:function(d,c){this.callbackManager.dispatchCallback(d,c)},clear:function(){this.clearExcept({})},clearRequest:function(e){if(e in this.requestsById){delete this.requestsById[e]}for(var c=0;c<this.requestQueue.length;c++){var d=this.requestQueue[c];if(d&&d.id==e){this.requestQueue[c]=null}}},clearExcept:function(g){for(var f=0;f<this.requestQueue.length;f++){var h=this.requestQueue[f];if(h&&!(h.id in g)){this.requestQueue[f]=null}}var c=this.loadingBay.childNodes;for(var e=c.length-1;e>=0;e--){var d=c[e];if(!(d.id in g)){this.loadingBay.removeChild(d);this.openRequestCount--;d.src=d.coord=d.onload=d.onerror=null}}for(var l in this.requestsById){if(this.requestsById.hasOwnProperty(l)){if(!(l in g)){var k=this.requestsById[l];delete this.requestsById[l];if(k!==null){k=k.id=k.coord=k.url=null}}}}},hasRequest:function(c){return(c in this.requestsById)},requestTile:function(f,e,c){if(!(f in this.requestsById)){var d={id:f,coord:e.copy(),url:c};this.requestsById[f]=d;if(c){this.requestQueue.push(d)}}},getProcessQueue:function(){if(!this._processQueue){var c=this;this._processQueue=function(){c.processQueue()}}return this._processQueue},processQueue:function(e){if(e&&this.requestQueue.length>8){this.requestQueue.sort(e)}while(this.openRequestCount<this.maxOpenRequests&&this.requestQueue.length>0){var d=this.requestQueue.pop();if(d){this.openRequestCount++;var c=document.createElement("img");c.id=d.id;c.style.position="absolute";c.coord=d.coord;this.loadingBay.appendChild(c);c.onload=c.onerror=this.getLoadComplete();c.src=d.url;d=d.id=d.coord=d.url=null}}},_loadComplete:null,getLoadComplete:function(){if(!this._loadComplete){var c=this;this._loadComplete=function(f){f=f||window.event;var d=f.srcElement||f.target;d.onload=d.onerror=null;c.loadingBay.removeChild(d);c.openRequestCount--;delete c.requestsById[d.id];if(f.type==="load"&&(d.complete||(d.readyState&&d.readyState=="complete"))){c.dispatchCallback("requestcomplete",d)}else{c.dispatchCallback("requesterror",d.src);d.src=null}setTimeout(c.getProcessQueue(),0)}}return this._loadComplete}};b.Layer=function(d,c){this.parent=c||document.createElement("div");this.parent.style.cssText="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; margin: 0; padding: 0; z-index: 0";this.levels={};this.requestManager=new b.RequestManager();this.requestManager.addCallback("requestcomplete",this.getTileComplete());if(d){this.setProvider(d)}};b.Layer.prototype={map:null,parent:null,tiles:null,levels:null,requestManager:null,tileCacheSize:null,maxTileCacheSize:null,provider:null,recentTiles:null,recentTilesById:null,enablePyramidLoading:false,_tileComplete:null,getTileComplete:function(){if(!this._tileComplete){var c=this;this._tileComplete=function(e,f){c.tiles[f.id]=f;c.tileCacheSize++;var d={id:f.id,lastTouchedTime:new Date().getTime()};c.recentTilesById[f.id]=d;c.recentTiles.push(d);c.positionTile(f)}}return this._tileComplete},draw:function(){var o=Math.round(this.map.coordinate.zoom);var n=this.map.pointCoordinate(new b.Point(0,0)).zoomTo(o).container();var i=this.map.pointCoordinate(this.map.dimensions).zoomTo(o).container().right().down();var k={};var m=this.createOrGetLevel(n.zoom);var h=n.copy();for(h.column=n.column;h.column<=i.column;h.column++){for(h.row=n.row;h.row<=i.row;h.row++){var d=this.inventoryVisibleTile(m,h);while(d.length){k[d.pop()]=true}}}for(var f in this.levels){if(this.levels.hasOwnProperty(f)){var p=parseInt(f,10);if(p>=n.zoom-5&&p<n.zoom+2){continue}var e=this.levels[f];e.style.display="none";var g=this.tileElementsInLevel(e);while(g.length){this.provider.releaseTile(g[0].coord);this.requestManager.clearRequest(g[0].coord.toKey());e.removeChild(g[0]);g.shift()}}}var c=n.zoom-5;var l=n.zoom+2;for(var j=c;j<l;j++){this.adjustVisibleLevel(this.levels[j],j,k)}this.requestManager.clearExcept(k);this.requestManager.processQueue(this.getCenterDistanceCompare());this.checkCache()},inventoryVisibleTile:function(q,d){var i=d.toKey(),e=[i];if(i in this.tiles){var h=this.tiles[i];if(h.parentNode!=q){q.appendChild(h);if("reAddTile" in this.provider){this.provider.reAddTile(i,d,h)}}return e}if(!this.requestManager.hasRequest(i)){var p=this.provider.getTile(d);if(typeof p=="string"){this.addTileImage(i,d,p)}else{if(p){this.addTileElement(i,d,p)}}}var f=false;var n=d.zoom;for(var j=1;j<=n;j++){var c=d.zoomBy(-j).container();var o=c.toKey();if(this.enablePyramidLoading){e.push(o);var m=this.createOrGetLevel(c.zoom);if(o in this.tiles){var l=this.tiles[o];if(l.parentNode!=m){m.appendChild(l)}}else{if(!this.requestManager.hasRequest(o)){var g=this.provider.getTile(c);if(typeof g=="string"){this.addTileImage(o,c,g)}else{this.addTileElement(o,c,g)}}}}else{if(o in this.tiles){e.push(o);f=true;break}}}if(!f&&!this.enablePyramidLoading){var k=d.zoomBy(1);e.push(k.toKey());k.column+=1;e.push(k.toKey());k.row+=1;e.push(k.toKey());k.column-=1;e.push(k.toKey())}return e},tileElementsInLevel:function(e){var c=[];for(var d=e.firstChild;d;d=d.nextSibling){if(d.nodeType==1){c.push(d)}}return c},adjustVisibleLevel:function(d,m,f){var e=new Date().getTime();if(!d){return}var g=1;var l=this.map.coordinate.copy();if(d.childNodes.length>0){d.style.display="block";g=Math.pow(2,this.map.coordinate.zoom-m);l=l.zoomTo(m)}else{d.style.display="none"}var j=this.map.tileSize.x*g;var h=this.map.tileSize.y*g;var c=new b.Point(this.map.dimensions.x/2,this.map.dimensions.y/2);var k=this.tileElementsInLevel(d);while(k.length){var i=k.pop();if(!f[i.id]){this.provider.releaseTile(i.coord);this.requestManager.clearRequest(i.coord.toKey());d.removeChild(i)}else{b.moveElement(i,{x:Math.round(c.x+(i.coord.column-l.column)*j),y:Math.round(c.y+(i.coord.row-l.row)*h),scale:g,width:this.map.tileSize.x,height:this.map.tileSize.y});this.recentTilesById[i.id].lastTouchedTime=e}}},createOrGetLevel:function(c){if(c in this.levels){return this.levels[c]}var d=document.createElement("div");d.id=this.parent.id+"-zoom-"+c;d.style.cssText=this.parent.style.cssText;d.style.zIndex=c;this.parent.appendChild(d);this.levels[c]=d;return d},addTileImage:function(d,e,c){this.requestManager.requestTile(d,e,c)},addTileElement:function(e,f,d){d.id=e;d.coord=f.copy();this.tiles[e]=d;this.tileCacheSize++;var c={id:e,lastTouchedTime:new Date().getTime()};this.recentTilesById[e]=c;this.recentTiles.push(c);this.positionTile(d)},positionTile:function(g){var f=this.map.coordinate.zoomTo(g.coord.zoom);var h=Math.pow(2,this.map.coordinate.zoom-g.coord.zoom);g.style.cssText="position:absolute;-webkit-user-select: none;-webkit-user-drag: none;-moz-user-drag: none;";g.ondragstart=function(){return false};var d=((this.map.dimensions.x/2)+(g.coord.column-f.column)*this.map.tileSize.x*h);var c=((this.map.dimensions.y/2)+(g.coord.row-f.row)*this.map.tileSize.y*h);b.moveElement(g,{x:Math.round(d),y:Math.round(c),scale:h,width:this.map.tileSize.x,height:this.map.tileSize.y});var e=this.levels[g.coord.zoom];e.appendChild(g);g.className="map-tile-loaded";if(Math.round(this.map.coordinate.zoom)==g.coord.zoom){e.style.display="block"}this.requestRedraw()},_redrawTimer:undefined,requestRedraw:function(){if(!this._redrawTimer){this._redrawTimer=setTimeout(this.getRedraw(),1000)}},_redraw:null,getRedraw:function(){if(!this._redraw){var c=this;this._redraw=function(){c.draw();c._redrawTimer=0}}return this._redraw},checkCache:function(){var g=this.parent.getElementsByTagName("img").length;var e=Math.max(g,this.maxTileCacheSize);if(this.tileCacheSize>e){this.recentTiles.sort(function(i,h){return h.lastTouchedTime<i.lastTouchedTime?-1:h.lastTouchedTime>i.lastTouchedTime?1:0})}while(this.tileCacheSize>e){var d=this.recentTiles.pop();var c=new Date().getTime();delete this.recentTilesById[d.id];var f=this.tiles[d.id];if(f.parentNode){alert("Gah: trying to removing cached tile even though it's still in the DOM")}else{delete this.tiles[d.id];this.tileCacheSize--}}},setProvider:function(d){var e=(this.provider===null);if(!e){this.requestManager.clear();for(var c in this.levels){if(this.levels.hasOwnProperty(c)){var f=this.levels[c];while(f.firstChild){this.provider.releaseTile(f.firstChild.coord);f.removeChild(f.firstChild)}}}}this.tiles={};this.tileCacheSize=0;this.maxTileCacheSize=64;this.recentTilesById={};this.recentTiles=[];this.provider=d;if(!e){this.draw()}},getCenterDistanceCompare:function(){var c=this.map.coordinate.zoomTo(Math.round(this.map.coordinate.zoom));return function(f,e){if(f&&e){var h=f.coord;var g=e.coord;if(h.zoom==g.zoom){var d=Math.abs(c.row-h.row-0.5)+Math.abs(c.column-h.column-0.5);var i=Math.abs(c.row-g.row-0.5)+Math.abs(c.column-g.column-0.5);return d<i?1:d>i?-1:0}else{return h.zoom<g.zoom?1:h.zoom>g.zoom?-1:0}}return f?1:e?-1:0}},destroy:function(){this.requestManager.clear();this.requestManager.removeCallback("requestcomplete",this.getTileComplete());this.provider=null;if(this.parent.parentNode){this.parent.parentNode.removeChild(this.parent)}this.map=null}};b.Map=function(g,f,h,k){if(typeof g=="string"){g=document.getElementById(g);if(!g){throw"The ID provided to modest maps could not be found."}}this.parent=g;this.parent.style.padding="0";this.parent.style.overflow="hidden";var c=b.getStyle(this.parent,"position");if(c!="relative"&&c!="absolute"){this.parent.style.position="relative"}this.layers=[];if(!(f instanceof Array)){f=[f]}for(var e=0;e<f.length;e++){this.addLayer(f[e])}this.projection=new b.MercatorProjection(0,b.deriveTransformation(-Math.PI,Math.PI,0,0,Math.PI,Math.PI,1,0,-Math.PI,-Math.PI,0,1));this.tileSize=new b.Point(256,256);this.coordLimits=[new b.Coordinate(0,-Infinity,0),new b.Coordinate(1,Infinity,0).zoomTo(18)];this.coordinate=new b.Coordinate(0.5,0.5,0);if(!h){h=new b.Point(this.parent.offsetWidth,this.parent.offsetHeight);this.autoSize=true;b.addEvent(window,"resize",this.windowResize())}else{this.autoSize=false;this.parent.style.width=Math.round(h.x)+"px";this.parent.style.height=Math.round(h.y)+"px"}this.dimensions=h;this.callbackManager=new b.CallbackManager(this,["zoomed","panned","centered","extentset","resized","drawn"]);if(k===undefined){this.eventHandlers=[new b.MouseHandler(this),new b.TouchHandler(this)]}else{this.eventHandlers=k;if(k instanceof Array){for(var d=0;d<k.length;d++){k[d].init(this)}}}};b.Map.prototype={parent:null,dimensions:null,projection:null,coordinate:null,tileSize:null,coordLimits:null,layers:null,callbackManager:null,eventHandlers:null,autoSize:null,toString:function(){return"Map(#"+this.parent.id+")"},addCallback:function(c,d){this.callbackManager.addCallback(c,d);return this},removeCallback:function(c,d){this.callbackManager.removeCallback(c,d);return this},dispatchCallback:function(d,c){this.callbackManager.dispatchCallback(d,c);return this},windowResize:function(){if(!this._windowResize){var c=this;this._windowResize=function(d){c.dimensions=new b.Point(c.parent.offsetWidth,c.parent.offsetHeight);c.draw();c.dispatchCallback("resized",[c.dimensions])}}return this._windowResize},setZoomRange:function(d,c){this.coordLimits[0]=this.coordLimits[0].zoomTo(d);this.coordLimits[1]=this.coordLimits[1].zoomTo(c)},zoomBy:function(c){this.coordinate=this.enforceLimits(this.coordinate.zoomBy(c));b.getFrame(this.getRedraw());this.dispatchCallback("zoomed",c);return this},zoomIn:function(){return this.zoomBy(1)},zoomOut:function(){return this.zoomBy(-1)},setZoom:function(c){return this.zoomBy(c-this.coordinate.zoom)},zoomByAbout:function(d,c){var f=this.pointLocation(c);this.coordinate=this.enforceLimits(this.coordinate.zoomBy(d));var e=this.locationPoint(f);this.dispatchCallback("zoomed",d);return this.panBy(c.x-e.x,c.y-e.y)},panBy:function(d,c){this.coordinate.column-=d/this.tileSize.x;this.coordinate.row-=c/this.tileSize.y;this.coordinate=this.enforceLimits(this.coordinate);b.getFrame(this.getRedraw());this.dispatchCallback("panned",[d,c]);return this},panLeft:function(){return this.panBy(100,0)},panRight:function(){return this.panBy(-100,0)},panDown:function(){return this.panBy(0,-100)},panUp:function(){return this.panBy(0,100)},setCenter:function(c){return this.setCenterZoom(c,this.coordinate.zoom)},setCenterZoom:function(c,d){this.coordinate=this.projection.locationCoordinate(c).zoomTo(parseFloat(d)||0);b.getFrame(this.getRedraw());this.dispatchCallback("centered",[c,d]);return this},setExtent:function(q,r){if(q instanceof b.Extent){q=q.toArray()}var u,k;for(var l=0;l<q.length;l++){var m=this.projection.locationCoordinate(q[l]);if(u){u.row=Math.min(u.row,m.row);u.column=Math.min(u.column,m.column);u.zoom=Math.min(u.zoom,m.zoom);k.row=Math.max(k.row,m.row);k.column=Math.max(k.column,m.column);k.zoom=Math.max(k.zoom,m.zoom)}else{u=m.copy();k=m.copy()}}var j=this.dimensions.x+1;var h=this.dimensions.y+1;var n=(k.column-u.column)/(j/this.tileSize.x);var s=Math.log(n)/Math.log(2);var o=u.zoom-(r?s:Math.ceil(s));var p=(k.row-u.row)/(h/this.tileSize.y);var e=Math.log(p)/Math.log(2);var f=u.zoom-(r?e:Math.ceil(e));var c=Math.min(o,f);c=Math.min(c,this.coordLimits[1].zoom);c=Math.max(c,this.coordLimits[0].zoom);var d=(u.row+k.row)/2;var t=(u.column+k.column)/2;var g=u.zoom;this.coordinate=new b.Coordinate(d,t,g).zoomTo(c);this.draw();this.dispatchCallback("extentset",q);return this},setSize:function(c){this.dimensions=new b.Point(c.x,c.y);this.parent.style.width=Math.round(this.dimensions.x)+"px";this.parent.style.height=Math.round(this.dimensions.y)+"px";if(this.autoSize){b.removeEvent(window,"resize",this.windowResize());this.autoSize=false}this.draw();this.dispatchCallback("resized",this.dimensions);return this},coordinatePoint:function(d){if(d.zoom!=this.coordinate.zoom){d=d.zoomTo(this.coordinate.zoom)}var c=new b.Point(this.dimensions.x/2,this.dimensions.y/2);c.x+=this.tileSize.x*(d.column-this.coordinate.column);c.y+=this.tileSize.y*(d.row-this.coordinate.row);return c},pointCoordinate:function(c){var d=this.coordinate.copy();d.column+=(c.x-this.dimensions.x/2)/this.tileSize.x;d.row+=(c.y-this.dimensions.y/2)/this.tileSize.y;return d},locationCoordinate:function(c){return this.projection.locationCoordinate(c)},coordinateLocation:function(c){return this.projection.coordinateLocation(c)},locationPoint:function(c){return this.coordinatePoint(this.locationCoordinate(c))},pointLocation:function(c){return this.coordinateLocation(this.pointCoordinate(c))},getExtent:function(){return new b.Extent(this.pointLocation(new b.Point(0,0)),this.pointLocation(this.dimensions))},extent:function(c,d){if(c){return this.setExtent(c,d)}else{return this.getExtent()}},getCenter:function(){return this.projection.coordinateLocation(this.coordinate)},center:function(c){if(c){return this.setCenter(c)}else{return this.getCenter()}},getZoom:function(){return this.coordinate.zoom},zoom:function(c){if(c!==undefined){return this.setZoom(c)}else{return this.getZoom()}},getLayers:function(){return this.layers.slice()},getLayerAt:function(c){return this.layers[c]},addLayer:function(c){this.layers.push(c);this.parent.appendChild(c.parent);c.map=this;return this},removeLayer:function(d){for(var c=0;c<this.layers.length;c++){if(d==this.layers[c]){this.removeLayerAt(c);break}}return this},setLayerAt:function(c,d){if(c<0||c>=this.layers.length){throw new Error("invalid index in setLayerAt(): "+c)}if(this.layers[c]!=d){if(c<this.layers.length){this.layers[c].destroy()}this.layers[c]=d;this.parent.appendChild(d.parent);d.map=this;b.getFrame(this.getRedraw())}return this},insertLayerAt:function(d,e){if(d<0||d>this.layers.length){throw new Error("invalid index in insertLayerAt(): "+d)}if(d==this.layers.length){this.layers.push(e);this.parent.appendChild(e.parent)}else{var c=this.layers[d];this.parent.insertBefore(e.parent,c.parent);this.layers.splice(d,0,e)}e.map=this;b.getFrame(this.getRedraw());return this},removeLayerAt:function(d){if(d<0||d>=this.layers.length){throw new Error("invalid index in removeLayer(): "+d)}var c=this.layers[d];this.layers.splice(d,1);c.destroy();return this},swapLayersAt:function(d,c){if(d<0||d>=this.layers.length||c<0||c>=this.layers.length){throw new Error("invalid index in swapLayersAt(): "+index)}var g=this.layers[d],e=this.layers[c],f=document.createElement("div");this.parent.replaceChild(f,e.parent);this.parent.replaceChild(e.parent,g.parent);this.parent.replaceChild(g.parent,f);this.layers[d]=e;this.layers[c]=g;return this},enforceZoomLimits:function(f){var d=this.coordLimits;if(d){var e=d[0].zoom;var c=d[1].zoom;if(f.zoom<e){f=f.zoomTo(e)}else{if(f.zoom>c){f=f.zoomTo(c)}}}return f},enforcePanLimits:function(h){var d=this.coordLimits;if(d){h=h.copy();var f=d[0].zoomTo(h.zoom);var c=d[1].zoomTo(h.zoom);var e=this.pointCoordinate(new b.Point(0,0));var g=this.pointCoordinate(this.dimensions);if(c.row-f.row<g.row-e.row){h.row=(c.row+f.row)/2}else{if(e.row<f.row){h.row+=f.row-e.row}else{if(g.row>c.row){h.row-=g.row-c.row}}}if(c.column-f.column<g.column-e.column){h.column=(c.column+f.column)/2}else{if(e.column<f.column){h.column+=f.column-e.column}else{if(g.column>c.column){h.column-=g.column-c.column}}}}return h},enforceLimits:function(c){return this.enforcePanLimits(this.enforceZoomLimits(c))},draw:function(){this.coordinate=this.enforceLimits(this.coordinate);if(this.dimensions.x<=0||this.dimensions.y<=0){if(this.autoSize){var c=this.parent.offsetWidth,e=this.parent.offsetHeight;this.dimensions=new b.Point(c,e);if(c<=0||e<=0){return}}else{return}}for(var d=0;d<this.layers.length;d++){this.layers[d].draw()}this.dispatchCallback("drawn")},_redrawTimer:undefined,requestRedraw:function(){if(!this._redrawTimer){this._redrawTimer=setTimeout(this.getRedraw(),1000)}},_redraw:null,getRedraw:function(){if(!this._redraw){var c=this;this._redraw=function(){c.draw();c._redrawTimer=0}}return this._redraw},destroy:function(){for(var c=0;c<this.layers.length;c++){this.layers[c].destroy()}this.layers=[];this.projection=null;for(var d=0;d<this.eventHandlers.length;d++){this.eventHandlers[d].remove()}if(this.autoSize){b.removeEvent(window,"resize",this.windowResize())}}};if(typeof module!=="undefined"&&module.exports){module.exports={Point:b.Point,Projection:b.Projection,MercatorProjection:b.MercatorProjection,LinearProjection:b.LinearProjection,Transformation:b.Transformation,Location:b.Location,MapProvider:b.MapProvider,TemplatedMapProvider:b.TemplatedMapProvider,Coordinate:b.Coordinate,deriveTransformation:b.deriveTransformation}}})(MM);
  14 +var previousMM=MM;if(!com){var com={};if(!com.modestmaps){com.modestmaps={}}}var MM=com.modestmaps={noConflict:function(){MM=previousMM;return this}};(function(b){b.extend=function(e,c){for(var d in c.prototype){if(typeof e.prototype[d]=="undefined"){e.prototype[d]=c.prototype[d]}}return e};b.getFrame=function(){return function(c){(window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(d){window.setTimeout(function(){d(+new Date())},10)})(c)}}();b.transformProperty=(function(e){if(!this.document){return}var d=document.documentElement.style;for(var c=0;c<e.length;c++){if(e[c] in d){return e[c]}}return false})(["transformProperty","WebkitTransform","OTransform","MozTransform","msTransform"]);b.matrixString=function(c){if(c.scale*c.width%1){c.scale+=(1-c.scale*c.width%1)/c.width}if(b._browser.webkit3d){return"matrix3d("+[(c.scale||"1"),"0,0,0,0",(c.scale||"1"),"0,0","0,0,1,0",(c.x+(((c.width*c.scale)-c.width)/2)).toFixed(4),(c.y+(((c.height*c.scale)-c.height)/2)).toFixed(4),0,1].join(",")+")"}else{var d=(b.transformProperty=="MozTransform")?"px":"";return"matrix("+[(c.scale||"1"),0,0,(c.scale||"1"),(c.x+(((c.width*c.scale)-c.width)/2))+d,(c.y+(((c.height*c.scale)-c.height)/2))+d].join(",")+")"}};b._browser=(function(c){return{webkit:("WebKitCSSMatrix" in c),webkit3d:("WebKitCSSMatrix" in c)&&("m11" in new WebKitCSSMatrix())}})(this);b.moveElement=function(e,c){if(b.transformProperty){if(!c.scale){c.scale=1}if(!c.width){c.width=0}if(!c.height){c.height=0}var d=b.matrixString(c);if(e[b.transformProperty]!==d){e.style[b.transformProperty]=e[b.transformProperty]=d}}else{e.style.left=c.x+"px";e.style.top=c.y+"px";if(c.width&&c.height&&c.scale){e.style.width=Math.ceil(c.width*c.scale)+"px";e.style.height=Math.ceil(c.height*c.scale)+"px"}}};b.cancelEvent=function(c){c.cancelBubble=true;c.cancel=true;c.returnValue=false;if(c.stopPropagation){c.stopPropagation()}if(c.preventDefault){c.preventDefault()}return false};b.bind=function(e,f){var g=Array.prototype.slice;var d=Function.prototype.bind;if(e.bind===d&&d){return d.apply(e,g.call(arguments,1))}var c=g.call(arguments,2);return function(){return e.apply(f,c.concat(g.call(arguments)))}};b.addEvent=function(e,d,c){if(e.addEventListener){e.addEventListener(d,c,false);if(d=="mousewheel"){e.addEventListener("DOMMouseScroll",c,false)}}else{if(e.attachEvent){e["e"+d+c]=c;e[d+c]=function(){e["e"+d+c](window.event)};e.attachEvent("on"+d,e[d+c])}}};b.removeEvent=function(e,d,c){if(e.removeEventListener){e.removeEventListener(d,c,false);if(d=="mousewheel"){e.removeEventListener("DOMMouseScroll",c,false)}}else{if(e.detachEvent){e.detachEvent("on"+d,e[d+c]);e[d+c]=null}}};b.getStyle=function(d,c){if(d.currentStyle){return d.currentStyle[c]}else{if(window.getComputedStyle){return document.defaultView.getComputedStyle(d,null).getPropertyValue(c)}}};b.Point=function(c,d){this.x=parseFloat(c);this.y=parseFloat(d)};b.Point.prototype={x:0,y:0,toString:function(){return"("+this.x.toFixed(3)+", "+this.y.toFixed(3)+")"},copy:function(){return new b.Point(this.x,this.y)}};b.Point.distance=function(f,e){var d=(e.x-f.x);var c=(e.y-f.y);return Math.sqrt(d*d+c*c)};b.Point.interpolate=function(g,f,e){var d=g.x+(f.x-g.x)*e;var c=g.y+(f.y-g.y)*e;return new b.Point(d,c)};b.Coordinate=function(e,c,d){this.row=e;this.column=c;this.zoom=d};b.Coordinate.prototype={row:0,column:0,zoom:0,toString:function(){return"("+this.row.toFixed(3)+", "+this.column.toFixed(3)+" @"+this.zoom.toFixed(3)+")"},toKey:function(){return[this.zoom,this.row,this.column].join(",")},copy:function(){return new b.Coordinate(this.row,this.column,this.zoom)},container:function(){return new b.Coordinate(Math.floor(this.row),Math.floor(this.column),Math.floor(this.zoom))},zoomTo:function(c){var d=Math.pow(2,c-this.zoom);return new b.Coordinate(this.row*d,this.column*d,c)},zoomBy:function(d){var c=Math.pow(2,d);return new b.Coordinate(this.row*c,this.column*c,this.zoom+d)},up:function(c){if(c===undefined){c=1}return new b.Coordinate(this.row-c,this.column,this.zoom)},right:function(c){if(c===undefined){c=1}return new b.Coordinate(this.row,this.column+c,this.zoom)},down:function(c){if(c===undefined){c=1}return new b.Coordinate(this.row+c,this.column,this.zoom)},left:function(c){if(c===undefined){c=1}return new b.Coordinate(this.row,this.column-c,this.zoom)}};b.Location=function(c,d){this.lat=parseFloat(c);this.lon=parseFloat(d)};b.Location.prototype={lat:0,lon:0,toString:function(){return"("+this.lat.toFixed(3)+", "+this.lon.toFixed(3)+")"},copy:function(){return new b.Location(this.lat,this.lon)}};b.Location.distance=function(j,i,f){if(!f){f=6378000}var p=Math.PI/180,h=j.lat*p,o=j.lon*p,g=i.lat*p,n=i.lon*p,m=Math.cos(h)*Math.cos(o)*Math.cos(g)*Math.cos(n),l=Math.cos(h)*Math.sin(o)*Math.cos(g)*Math.sin(n),k=Math.sin(h)*Math.sin(g);return Math.acos(m+l+k)*f};b.Location.interpolate=function(j,h,n){if(j.lat===h.lat&&j.lon===h.lon){return new b.Location(j.lat,j.lon)}var t=Math.PI/180,l=j.lat*t,o=j.lon*t,k=h.lat*t,m=h.lon*t;var p=2*Math.asin(Math.sqrt(Math.pow(Math.sin((l-k)/2),2)+Math.cos(l)*Math.cos(k)*Math.pow(Math.sin((o-m)/2),2)));var u=Math.atan2(Math.sin(o-m)*Math.cos(k),Math.cos(l)*Math.sin(k)-Math.sin(l)*Math.cos(k)*Math.cos(o-m))/-(Math.PI/180);u=u<0?360+u:u;var g=Math.sin((1-n)*p)/Math.sin(p);var c=Math.sin(n*p)/Math.sin(p);var s=g*Math.cos(l)*Math.cos(o)+c*Math.cos(k)*Math.cos(m);var r=g*Math.cos(l)*Math.sin(o)+c*Math.cos(k)*Math.sin(m);var q=g*Math.sin(l)+c*Math.sin(k);var e=Math.atan2(q,Math.sqrt(Math.pow(s,2)+Math.pow(r,2)));var i=Math.atan2(r,s);return new b.Location(e/t,i/t)};b.Extent=function(h,d,g,f){if(arguments[0] instanceof b.Location){var e=arguments[0];h=e.lat;d=e.lon}if(arguments[1] instanceof b.Location){var c=arguments[1];g=c.lat;f=c.lon}if(isNaN(g)){g=h}if(isNaN(f)){f=d}this.north=Math.max(h,g);this.south=Math.min(h,g);this.east=Math.max(f,d);this.west=Math.min(f,d)};b.Extent.prototype={north:0,south:0,east:0,west:0,copy:function(){return new b.Extent(this.north,this.west,this.south,this.east)},toString:function(c){if(isNaN(c)){c=3}return[this.north.toFixed(c),this.west.toFixed(c),this.south.toFixed(c),this.east.toFixed(c)].join(", ")},northWest:function(){return new b.Location(this.north,this.west)},southEast:function(){return new b.Location(this.south,this.east)},northEast:function(){return new b.Location(this.north,this.east)},southWest:function(){return new b.Location(this.south,this.west)},center:function(){return new b.Location(this.south+(this.north-this.south)/2,this.east+(this.west-this.east)/2)},encloseLocation:function(c){if(c.lat>this.north){this.north=c.lat}if(c.lat<this.south){this.south=c.lat}if(c.lon>this.east){this.east=c.lon}if(c.lon<this.west){this.west=c.lon}},encloseLocations:function(d){var c=d.length;for(var e=0;e<c;e++){this.encloseLocation(d[e])}},setFromLocations:function(d){var c=d.length,f=d[0];this.north=this.south=f.lat;this.east=this.west=f.lon;for(var e=1;e<c;e++){this.encloseLocation(d[e])}},encloseExtent:function(c){if(c.north>this.north){this.north=c.north}if(c.south<this.south){this.south=c.south}if(c.east>this.east){this.east=c.east}if(c.west<this.west){this.west=c.west}},containsLocation:function(c){return c.lat>=this.south&&c.lat<=this.north&&c.lon>=this.west&&c.lon<=this.east},toArray:function(){return[this.northWest(),this.southEast()]}};b.Extent.fromString=function(d){var c=d.split(/\s*,\s*/);if(c.length!=4){throw"Invalid extent string (expecting 4 comma-separated numbers)"}return new b.Extent(parseFloat(c[0]),parseFloat(c[1]),parseFloat(c[2]),parseFloat(c[3]))};b.Extent.fromArray=function(c){var d=new b.Extent();d.setFromLocations(c);return d};b.Transformation=function(e,g,c,d,f,h){this.ax=e;this.bx=g;this.cx=c;this.ay=d;this.by=f;this.cy=h};b.Transformation.prototype={ax:0,bx:0,cx:0,ay:0,by:0,cy:0,transform:function(c){return new b.Point(this.ax*c.x+this.bx*c.y+this.cx,this.ay*c.x+this.by*c.y+this.cy)},untransform:function(c){return new b.Point((c.x*this.by-c.y*this.bx-this.cx*this.by+this.cy*this.bx)/(this.ax*this.by-this.ay*this.bx),(c.x*this.ay-c.y*this.ax-this.cx*this.ay+this.cy*this.ax)/(this.bx*this.ay-this.by*this.ax))}};b.deriveTransformation=function(m,l,g,f,c,p,i,h,e,d,o,n){var k=b.linearSolution(m,l,g,c,p,i,e,d,o);var j=b.linearSolution(m,l,f,c,p,h,e,d,n);return new b.Transformation(k[0],k[1],k[2],j[0],j[1],j[2])};b.linearSolution=function(f,o,i,e,n,h,d,m,g){f=parseFloat(f);o=parseFloat(o);i=parseFloat(i);e=parseFloat(e);n=parseFloat(n);h=parseFloat(h);d=parseFloat(d);m=parseFloat(m);g=parseFloat(g);var l=(((h-g)*(o-n))-((i-h)*(n-m)))/(((e-d)*(o-n))-((f-e)*(n-m)));var k=(((h-g)*(f-e))-((i-h)*(e-d)))/(((n-m)*(f-e))-((o-n)*(e-d)));var j=i-(f*l)-(o*k);return[l,k,j]};b.Projection=function(d,c){if(!c){c=new b.Transformation(1,0,0,0,1,0)}this.zoom=d;this.transformation=c};b.Projection.prototype={zoom:0,transformation:null,rawProject:function(c){throw"Abstract method not implemented by subclass."},rawUnproject:function(c){throw"Abstract method not implemented by subclass."},project:function(c){c=this.rawProject(c);if(this.transformation){c=this.transformation.transform(c)}return c},unproject:function(c){if(this.transformation){c=this.transformation.untransform(c)}c=this.rawUnproject(c);return c},locationCoordinate:function(d){var c=new b.Point(Math.PI*d.lon/180,Math.PI*d.lat/180);c=this.project(c);return new b.Coordinate(c.y,c.x,this.zoom)},coordinateLocation:function(d){d=d.zoomTo(this.zoom);var c=new b.Point(d.column,d.row);c=this.unproject(c);return new b.Location(180*c.y/Math.PI,180*c.x/Math.PI)}};b.LinearProjection=function(d,c){b.Projection.call(this,d,c)};b.LinearProjection.prototype={rawProject:function(c){return new b.Point(c.x,c.y)},rawUnproject:function(c){return new b.Point(c.x,c.y)}};b.extend(b.LinearProjection,b.Projection);b.MercatorProjection=function(d,c){b.Projection.call(this,d,c)};b.MercatorProjection.prototype={rawProject:function(c){return new b.Point(c.x,Math.log(Math.tan(0.25*Math.PI+0.5*c.y)))},rawUnproject:function(c){return new b.Point(c.x,2*Math.atan(Math.pow(Math.E,c.y))-0.5*Math.PI)}};b.extend(b.MercatorProjection,b.Projection);b.MapProvider=function(c){if(c){this.getTile=c}};b.MapProvider.prototype={tileLimits:[new b.Coordinate(0,0,0),new b.Coordinate(1,1,0).zoomTo(18)],getTileUrl:function(c){throw"Abstract method not implemented by subclass."},getTile:function(c){throw"Abstract method not implemented by subclass."},releaseTile:function(c){},setZoomRange:function(d,c){this.tileLimits[0]=this.tileLimits[0].zoomTo(d);this.tileLimits[1]=this.tileLimits[1].zoomTo(c)},sourceCoordinate:function(g){var d=this.tileLimits[0].zoomTo(g.zoom),e=this.tileLimits[1].zoomTo(g.zoom),c=Math.pow(2,g.zoom),f;if(g.column<0){f=(g.column+c)%c}else{f=g.column%c}if(g.row<d.row||g.row>=e.row){return null}else{if(f<d.column||f>=e.column){return null}else{return new b.Coordinate(g.row,f,g.zoom)}}}};b.TemplatedMapProvider=function(e,c){var f=e.match(/{(Q|quadkey)}/);if(f){e=e.replace("{subdomains}","{S}").replace("{zoom}","{Z}").replace("{quadkey}","{Q}")}var d=(c&&c.length&&e.indexOf("{S}")>=0);var g=function(k){var j=this.sourceCoordinate(k);if(!j){return null}var i=e;if(d){var h=parseInt(j.zoom+j.row+j.column,10)%c.length;i=i.replace("{S}",c[h])}if(f){return i.replace("{Z}",j.zoom.toFixed(0)).replace("{Q}",this.quadKey(j.row,j.column,j.zoom))}else{return i.replace("{Z}",j.zoom.toFixed(0)).replace("{X}",j.column.toFixed(0)).replace("{Y}",j.row.toFixed(0))}};b.MapProvider.call(this,g)};b.TemplatedMapProvider.prototype={quadKey:function(g,e,f){var d="";for(var c=1;c<=f;c++){d+=(((g>>f-c)&1)<<1)|((e>>f-c)&1)}return d||"0"},getTile:function(c){return this.getTileUrl(c)}};b.extend(b.TemplatedMapProvider,b.MapProvider);b.TemplatedLayer=function(d,c){return new b.Layer(new b.TemplatedMapProvider(d,c))};b.getMousePoint=function(g,f){var c=new b.Point(g.clientX,g.clientY);c.x+=document.body.scrollLeft+document.documentElement.scrollLeft;c.y+=document.body.scrollTop+document.documentElement.scrollTop;for(var d=f.parent;d;d=d.offsetParent){c.x-=d.offsetLeft;c.y-=d.offsetTop}return c};b.MouseWheelHandler=function(d,c){if(d){this.init(d,c)}else{if(arguments.length>1){this.precise=c?true:false}}};b.MouseWheelHandler.prototype={precise:false,init:function(d){this.map=d;this._mouseWheel=b.bind(this.mouseWheel,this);this._zoomDiv=document.body.appendChild(document.createElement("div"));this._zoomDiv.style.cssText="visibility:hidden;top:0;height:0;width:0;overflow-y:scroll";var c=this._zoomDiv.appendChild(document.createElement("div"));c.style.height="2000px";b.addEvent(d.parent,"mousewheel",this._mouseWheel)},remove:function(){b.removeEvent(this.map.parent,"mousewheel",this._mouseWheel);this._zoomDiv.parentNode.removeChild(this._zoomDiv)},mouseWheel:function(g){var h=0;this.prevTime=this.prevTime||new Date().getTime();try{this._zoomDiv.scrollTop=1000;this._zoomDiv.dispatchEvent(g);h=1000-this._zoomDiv.scrollTop}catch(d){h=g.wheelDelta||(-g.detail*5)}var f=new Date().getTime()-this.prevTime;if(Math.abs(h)>0&&(f>200)&&!this.precise){var c=b.getMousePoint(g,this.map);this.map.zoomByAbout(h>0?1:-1,c);this.prevTime=new Date().getTime()}else{if(this.precise){var c=b.getMousePoint(g,this.map);this.map.zoomByAbout(h*0.001,c)}}return b.cancelEvent(g)}};b.DoubleClickHandler=function(c){if(c!==undefined){this.init(c)}};b.DoubleClickHandler.prototype={init:function(c){this.map=c;this._doubleClick=b.bind(this.doubleClick,this);b.addEvent(c.parent,"dblclick",this._doubleClick)},remove:function(){b.removeEvent(this.map.parent,"dblclick",this._doubleClick)},doubleClick:function(d){var c=b.getMousePoint(d,this.map);this.map.zoomByAbout(d.shiftKey?-1:1,c);return b.cancelEvent(d)}};b.DragHandler=function(c){if(c!==undefined){this.init(c)}};b.DragHandler.prototype={init:function(c){this.map=c;this._mouseDown=b.bind(this.mouseDown,this);b.addEvent(c.parent,"mousedown",this._mouseDown)},remove:function(){b.removeEvent(this.map.parent,"mousedown",this._mouseDown)},mouseDown:function(c){b.addEvent(document,"mouseup",this._mouseUp=b.bind(this.mouseUp,this));b.addEvent(document,"mousemove",this._mouseMove=b.bind(this.mouseMove,this));this.prevMouse=new b.Point(c.clientX,c.clientY);this.map.parent.style.cursor="move";return b.cancelEvent(c)},mouseMove:function(c){if(this.prevMouse){this.map.panBy(c.clientX-this.prevMouse.x,c.clientY-this.prevMouse.y);this.prevMouse.x=c.clientX;this.prevMouse.y=c.clientY;this.prevMouse.t=+new Date()}return b.cancelEvent(c)},mouseUp:function(c){b.removeEvent(document,"mouseup",this._mouseUp);b.removeEvent(document,"mousemove",this._mouseMove);this.prevMouse=null;this.map.parent.style.cursor="";return b.cancelEvent(c)}};b.MouseHandler=function(c){if(c!==undefined){this.init(c)}};b.MouseHandler.prototype={init:function(c){this.map=c;this.handlers=[new b.DragHandler(c),new b.DoubleClickHandler(c),new b.MouseWheelHandler(c)]},remove:function(){for(var c=0;c<this.handlers.length;c++){this.handlers[c].remove()}}};var a=(function(){var c=window.documentMode;return("onhashchange" in window)&&(c===undefined||c>7)})();b.Hash=function(c){this.onMapMove=b.bind(this.onMapMove,this);this.onHashChange=b.bind(this.onHashChange,this);if(c){this.init(c)}};b.Hash.prototype={map:null,lastHash:null,parseHash:function(f){var c=f.split("/");if(c.length==3){var d=parseInt(c[0],10),e=parseFloat(c[1]),g=parseFloat(c[2]);if(isNaN(d)||isNaN(e)||isNaN(g)){return false}else{return{center:new b.Location(e,g),zoom:d}}}else{return false}},formatHash:function(f){var c=f.getCenter(),e=f.getZoom(),d=Math.max(0,Math.ceil(Math.log(e)/Math.LN2));return"#"+[e,c.lat.toFixed(d),c.lon.toFixed(d)].join("/")},init:function(c){this.map=c;this.map.addCallback("drawn",this.onMapMove);this.lastHash=null;this.onHashChange();if(!this.isListening){this.startListening()}},remove:function(){this.map=null;if(this.isListening){this.stopListening()}},onMapMove:function(d){if(this.movingMap||this.map.zoom===0){return false}var c=this.formatHash(d);if(this.lastHash!=c){location.replace(c);this.lastHash=c}},movingMap:false,update:function(){var e=location.hash;if(e===this.lastHash){return}var d=e.substr(1),c=this.parseHash(d);if(c){this.movingMap=true;this.map.setCenterZoom(c.center,c.zoom);this.movingMap=false}else{this.onMapMove(this.map)}},changeDefer:100,changeTimeout:null,onHashChange:function(){if(!this.changeTimeout){var c=this;this.changeTimeout=setTimeout(function(){c.update();c.changeTimeout=null},this.changeDefer)}},isListening:false,hashChangeInterval:null,startListening:function(){if(a){window.addEventListener("hashchange",this.onHashChange,false)}else{clearInterval(this.hashChangeInterval);this.hashChangeInterval=setInterval(this.onHashChange,50)}this.isListening=true},stopListening:function(){if(a){window.removeEventListener("hashchange",this.onHashChange)}else{clearInterval(this.hashChangeInterval)}this.isListening=false}};b.TouchHandler=function(d,c){if(d){this.init(d,c)}};b.TouchHandler.prototype={maxTapTime:250,maxTapDistance:30,maxDoubleTapDelay:350,locations:{},taps:[],wasPinching:false,lastPinchCenter:null,init:function(d,c){this.map=d;c=c||{};if(!this.isTouchable()){return false}this._touchStartMachine=b.bind(this.touchStartMachine,this);this._touchMoveMachine=b.bind(this.touchMoveMachine,this);this._touchEndMachine=b.bind(this.touchEndMachine,this);b.addEvent(d.parent,"touchstart",this._touchStartMachine);b.addEvent(d.parent,"touchmove",this._touchMoveMachine);b.addEvent(d.parent,"touchend",this._touchEndMachine);this.options={};this.options.snapToZoom=c.snapToZoom||true},isTouchable:function(){var c=document.createElement("div");c.setAttribute("ongesturestart","return;");return(typeof c.ongesturestart==="function")},remove:function(){if(!this.isTouchable()){return false}b.removeEvent(this.map.parent,"touchstart",this._touchStartMachine);b.removeEvent(this.map.parent,"touchmove",this._touchMoveMachine);b.removeEvent(this.map.parent,"touchend",this._touchEndMachine)},updateTouches:function(g){for(var f=0;f<g.touches.length;f+=1){var d=g.touches[f];if(d.identifier in this.locations){var c=this.locations[d.identifier];c.x=d.screenX;c.y=d.screenY;c.scale=g.scale}else{this.locations[d.identifier]={scale:g.scale,startPos:{x:d.screenX,y:d.screenY},x:d.screenX,y:d.screenY,time:new Date().getTime()}}}},sameTouch:function(c,d){return(c&&c.touch)&&(d.identifier==c.touch.identifier)},touchStartMachine:function(c){this.updateTouches(c);return b.cancelEvent(c)},touchMoveMachine:function(c){switch(c.touches.length){case 1:this.onPanning(c.touches[0]);break;case 2:this.onPinching(c);break}this.updateTouches(c);return b.cancelEvent(c)},touchEndMachine:function(m){var d=new Date().getTime();if(m.touches.length===0&&this.wasPinching){this.onPinched(this.lastPinchCenter)}for(var k=0;k<m.changedTouches.length;k+=1){var p=m.changedTouches[k],l=this.locations[p.identifier];if(!l||l.wasPinch){continue}var o={x:p.screenX,y:p.screenY},g=d-l.time,f=b.Point.distance(o,l.startPos);if(f>this.maxTapDistance){}else{if(g>this.maxTapTime){o.end=d;o.duration=g;this.onHold(o)}else{o.time=d;this.onTap(o)}}}var n={};for(var h=0;h<m.touches.length;h++){n[m.touches[h].identifier]=true}for(var c in this.locations){if(!(c in n)){delete n[c]}}return b.cancelEvent(m)},onHold:function(c){},onTap:function(c){if(this.taps.length&&(c.time-this.taps[0].time)<this.maxDoubleTapDelay){this.onDoubleTap(c);this.taps=[];return}this.taps=[c]},onDoubleTap:function(d){var f=this.map.getZoom(),g=Math.round(f)+1,c=g-f;var e=new b.Point(d.x,d.y);this.map.zoomByAbout(c,e)},onPanning:function(e){var d={x:e.screenX,y:e.screenY},c=this.locations[e.identifier];this.map.panBy(d.x-c.x,d.y-c.y)},onPinching:function(j){var i=j.touches[0],h=j.touches[1],l=new b.Point(i.screenX,i.screenY),k=new b.Point(h.screenX,h.screenY),f=this.locations[i.identifier],d=this.locations[h.identifier];f.wasPinch=true;d.wasPinch=true;var c=b.Point.interpolate(l,k,0.5);this.map.zoomByAbout(Math.log(j.scale)/Math.LN2-Math.log(f.scale)/Math.LN2,c);var g=b.Point.interpolate(f,d,0.5);this.map.panBy(c.x-g.x,c.y-g.y);this.wasPinching=true;this.lastPinchCenter=c},onPinched:function(c){if(this.options.snapToZoom){var d=this.map.getZoom(),e=Math.round(d);this.map.zoomByAbout(e-d,c)}this.wasPinching=false}};b.CallbackManager=function(c,e){this.owner=c;this.callbacks={};for(var d=0;d<e.length;d++){this.callbacks[e[d]]=[]}};b.CallbackManager.prototype={owner:null,callbacks:null,addCallback:function(c,d){if(typeof(d)=="function"&&this.callbacks[c]){this.callbacks[c].push(d)}},removeCallback:function(f,g){if(typeof(g)=="function"&&this.callbacks[f]){var d=this.callbacks[f],c=d.length;for(var e=0;e<c;e++){if(d[e]===g){d.splice(e,1);break}}}},dispatchCallback:function(f,d){if(this.callbacks[f]){for(var c=0;c<this.callbacks[f].length;c+=1){try{this.callbacks[f][c](this.owner,d)}catch(g){}}}}};b.RequestManager=function(){this.loadingBay=document.createDocumentFragment();this.requestsById={};this.openRequestCount=0;this.maxOpenRequests=4;this.requestQueue=[];this.callbackManager=new b.CallbackManager(this,["requestcomplete","requesterror"])};b.RequestManager.prototype={loadingBay:null,requestsById:null,requestQueue:null,openRequestCount:null,maxOpenRequests:null,callbackManager:null,addCallback:function(c,d){this.callbackManager.addCallback(c,d)},removeCallback:function(c,d){this.callbackManager.removeCallback(c,d)},dispatchCallback:function(d,c){this.callbackManager.dispatchCallback(d,c)},clear:function(){this.clearExcept({})},clearRequest:function(e){if(e in this.requestsById){delete this.requestsById[e]}for(var c=0;c<this.requestQueue.length;c++){var d=this.requestQueue[c];if(d&&d.id==e){this.requestQueue[c]=null}}},clearExcept:function(g){for(var f=0;f<this.requestQueue.length;f++){var h=this.requestQueue[f];if(h&&!(h.id in g)){this.requestQueue[f]=null}}var c=this.loadingBay.childNodes;for(var e=c.length-1;e>=0;e--){var d=c[e];if(!(d.id in g)){this.loadingBay.removeChild(d);this.openRequestCount--;d.src=d.coord=d.onload=d.onerror=null}}for(var l in this.requestsById){if(this.requestsById.hasOwnProperty(l)){if(!(l in g)){var k=this.requestsById[l];delete this.requestsById[l];if(k!==null){k=k.id=k.coord=k.url=null}}}}},hasRequest:function(c){return(c in this.requestsById)},requestTile:function(f,e,c){if(!(f in this.requestsById)){var d={id:f,coord:e.copy(),url:c};this.requestsById[f]=d;if(c){this.requestQueue.push(d)}}},getProcessQueue:function(){if(!this._processQueue){var c=this;this._processQueue=function(){c.processQueue()}}return this._processQueue},processQueue:function(e){if(e&&this.requestQueue.length>8){this.requestQueue.sort(e)}while(this.openRequestCount<this.maxOpenRequests&&this.requestQueue.length>0){var d=this.requestQueue.pop();if(d){this.openRequestCount++;var c=document.createElement("img");c.id=d.id;c.style.position="absolute";c.coord=d.coord;this.loadingBay.appendChild(c);c.onload=c.onerror=this.getLoadComplete();c.src=d.url;d=d.id=d.coord=d.url=null}}},_loadComplete:null,getLoadComplete:function(){if(!this._loadComplete){var c=this;this._loadComplete=function(f){f=f||window.event;var d=f.srcElement||f.target;d.onload=d.onerror=null;c.loadingBay.removeChild(d);c.openRequestCount--;delete c.requestsById[d.id];if(f.type==="load"&&(d.complete||(d.readyState&&d.readyState=="complete"))){c.dispatchCallback("requestcomplete",d)}else{c.dispatchCallback("requesterror",d.src);d.src=null}setTimeout(c.getProcessQueue(),0)}}return this._loadComplete}};b.Layer=function(d,c){this.parent=c||document.createElement("div");this.parent.style.cssText="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; margin: 0; padding: 0; z-index: 0";this.levels={};this.requestManager=new b.RequestManager();this.requestManager.addCallback("requestcomplete",this.getTileComplete());if(d){this.setProvider(d)}};b.Layer.prototype={map:null,parent:null,tiles:null,levels:null,requestManager:null,tileCacheSize:null,maxTileCacheSize:null,provider:null,recentTiles:null,recentTilesById:null,enablePyramidLoading:false,_tileComplete:null,getTileComplete:function(){if(!this._tileComplete){var c=this;this._tileComplete=function(e,f){c.tiles[f.id]=f;c.tileCacheSize++;var d={id:f.id,lastTouchedTime:new Date().getTime()};c.recentTilesById[f.id]=d;c.recentTiles.push(d);c.positionTile(f)}}return this._tileComplete},draw:function(){var o=Math.round(this.map.coordinate.zoom);var n=this.map.pointCoordinate(new b.Point(0,0)).zoomTo(o).container();var i=this.map.pointCoordinate(this.map.dimensions).zoomTo(o).container().right().down();var k={};var m=this.createOrGetLevel(n.zoom);var h=n.copy();for(h.column=n.column;h.column<=i.column;h.column++){for(h.row=n.row;h.row<=i.row;h.row++){var d=this.inventoryVisibleTile(m,h);while(d.length){k[d.pop()]=true}}}for(var f in this.levels){if(this.levels.hasOwnProperty(f)){var p=parseInt(f,10);if(p>=n.zoom-5&&p<n.zoom+2){continue}var e=this.levels[f];e.style.display="none";var g=this.tileElementsInLevel(e);while(g.length){this.provider.releaseTile(g[0].coord);this.requestManager.clearRequest(g[0].coord.toKey());e.removeChild(g[0]);g.shift()}}}var c=n.zoom-5;var l=n.zoom+2;for(var j=c;j<l;j++){this.adjustVisibleLevel(this.levels[j],j,k)}this.requestManager.clearExcept(k);this.requestManager.processQueue(this.getCenterDistanceCompare());this.checkCache()},inventoryVisibleTile:function(q,d){var i=d.toKey(),e=[i];if(i in this.tiles){var h=this.tiles[i];if(h.parentNode!=q){q.appendChild(h);if("reAddTile" in this.provider){this.provider.reAddTile(i,d,h)}}return e}if(!this.requestManager.hasRequest(i)){var p=this.provider.getTile(d);if(typeof p=="string"){this.addTileImage(i,d,p)}else{if(p){this.addTileElement(i,d,p)}}}var f=false;var n=d.zoom;for(var j=1;j<=n;j++){var c=d.zoomBy(-j).container();var o=c.toKey();if(this.enablePyramidLoading){e.push(o);var m=this.createOrGetLevel(c.zoom);if(o in this.tiles){var l=this.tiles[o];if(l.parentNode!=m){m.appendChild(l)}}else{if(!this.requestManager.hasRequest(o)){var g=this.provider.getTile(c);if(typeof g=="string"){this.addTileImage(o,c,g)}else{this.addTileElement(o,c,g)}}}}else{if(o in this.tiles){e.push(o);f=true;break}}}if(!f&&!this.enablePyramidLoading){var k=d.zoomBy(1);e.push(k.toKey());k.column+=1;e.push(k.toKey());k.row+=1;e.push(k.toKey());k.column-=1;e.push(k.toKey())}return e},tileElementsInLevel:function(e){var c=[];for(var d=e.firstChild;d;d=d.nextSibling){if(d.nodeType==1){c.push(d)}}return c},adjustVisibleLevel:function(d,m,f){var e=new Date().getTime();if(!d){return}var g=1;var l=this.map.coordinate.copy();if(d.childNodes.length>0){d.style.display="block";g=Math.pow(2,this.map.coordinate.zoom-m);l=l.zoomTo(m)}else{d.style.display="none"}var j=this.map.tileSize.x*g;var h=this.map.tileSize.y*g;var c=new b.Point(this.map.dimensions.x/2,this.map.dimensions.y/2);var k=this.tileElementsInLevel(d);while(k.length){var i=k.pop();if(!f[i.id]){this.provider.releaseTile(i.coord);this.requestManager.clearRequest(i.coord.toKey());d.removeChild(i)}else{b.moveElement(i,{x:Math.round(c.x+(i.coord.column-l.column)*j),y:Math.round(c.y+(i.coord.row-l.row)*h),scale:g,width:this.map.tileSize.x,height:this.map.tileSize.y});this.recentTilesById[i.id].lastTouchedTime=e}}},createOrGetLevel:function(c){if(c in this.levels){return this.levels[c]}var d=document.createElement("div");d.id=this.parent.id+"-zoom-"+c;d.style.cssText=this.parent.style.cssText;d.style.zIndex=c;this.parent.appendChild(d);this.levels[c]=d;return d},addTileImage:function(d,e,c){this.requestManager.requestTile(d,e,c)},addTileElement:function(e,f,d){d.id=e;d.coord=f.copy();this.tiles[e]=d;this.tileCacheSize++;var c={id:e,lastTouchedTime:new Date().getTime()};this.recentTilesById[e]=c;this.recentTiles.push(c);this.positionTile(d)},positionTile:function(g){var f=this.map.coordinate.zoomTo(g.coord.zoom);var h=Math.pow(2,this.map.coordinate.zoom-g.coord.zoom);g.style.cssText="position:absolute;-webkit-user-select: none;-webkit-user-drag: none;-moz-user-drag: none;";g.ondragstart=function(){return false};var d=((this.map.dimensions.x/2)+(g.coord.column-f.column)*this.map.tileSize.x*h);var c=((this.map.dimensions.y/2)+(g.coord.row-f.row)*this.map.tileSize.y*h);b.moveElement(g,{x:Math.round(d),y:Math.round(c),scale:h,width:this.map.tileSize.x,height:this.map.tileSize.y});var e=this.levels[g.coord.zoom];e.appendChild(g);g.className="map-tile-loaded";if(Math.round(this.map.coordinate.zoom)==g.coord.zoom){e.style.display="block"}this.requestRedraw()},_redrawTimer:undefined,requestRedraw:function(){if(!this._redrawTimer){this._redrawTimer=setTimeout(this.getRedraw(),1000)}},_redraw:null,getRedraw:function(){if(!this._redraw){var c=this;this._redraw=function(){c.draw();c._redrawTimer=0}}return this._redraw},checkCache:function(){var g=this.parent.getElementsByTagName("img").length;var e=Math.max(g,this.maxTileCacheSize);if(this.tileCacheSize>e){this.recentTiles.sort(function(i,h){return h.lastTouchedTime<i.lastTouchedTime?-1:h.lastTouchedTime>i.lastTouchedTime?1:0})}while(this.tileCacheSize>e){var d=this.recentTiles.pop();var c=new Date().getTime();delete this.recentTilesById[d.id];var f=this.tiles[d.id];if(f.parentNode){alert("Gah: trying to removing cached tile even though it's still in the DOM")}else{delete this.tiles[d.id];this.tileCacheSize--}}},setProvider:function(d){var e=(this.provider===null);if(!e){this.requestManager.clear();for(var c in this.levels){if(this.levels.hasOwnProperty(c)){var f=this.levels[c];while(f.firstChild){this.provider.releaseTile(f.firstChild.coord);f.removeChild(f.firstChild)}}}}this.tiles={};this.tileCacheSize=0;this.maxTileCacheSize=64;this.recentTilesById={};this.recentTiles=[];this.provider=d;if(!e){this.draw()}},getCenterDistanceCompare:function(){var c=this.map.coordinate.zoomTo(Math.round(this.map.coordinate.zoom));return function(f,e){if(f&&e){var h=f.coord;var g=e.coord;if(h.zoom==g.zoom){var d=Math.abs(c.row-h.row-0.5)+Math.abs(c.column-h.column-0.5);var i=Math.abs(c.row-g.row-0.5)+Math.abs(c.column-g.column-0.5);return d<i?1:d>i?-1:0}else{return h.zoom<g.zoom?1:h.zoom>g.zoom?-1:0}}return f?1:e?-1:0}},destroy:function(){this.requestManager.clear();this.requestManager.removeCallback("requestcomplete",this.getTileComplete());this.provider=null;if(this.parent.parentNode){this.parent.parentNode.removeChild(this.parent)}this.map=null}};b.Map=function(g,f,h,k){if(typeof g=="string"){g=document.getElementById(g);if(!g){throw"The ID provided to modest maps could not be found."}}this.parent=g;this.parent.style.padding="0";this.parent.style.overflow="hidden";var c=b.getStyle(this.parent,"position");if(c!="relative"&&c!="absolute"){this.parent.style.position="relative"}this.layers=[];if(!(f instanceof Array)){f=[f]}for(var e=0;e<f.length;e++){this.addLayer(f[e])}this.projection=new b.MercatorProjection(0,b.deriveTransformation(-Math.PI,Math.PI,0,0,Math.PI,Math.PI,1,0,-Math.PI,-Math.PI,0,1));this.tileSize=new b.Point(256,256);this.coordLimits=[new b.Coordinate(0,-Infinity,0),new b.Coordinate(1,Infinity,0).zoomTo(18)];this.coordinate=new b.Coordinate(0.5,0.5,0);if(!h){h=new b.Point(this.parent.offsetWidth,this.parent.offsetHeight);this.autoSize=true;b.addEvent(window,"resize",this.windowResize())}else{this.autoSize=false;this.parent.style.width=Math.round(h.x)+"px";this.parent.style.height=Math.round(h.y)+"px"}this.dimensions=h;this.callbackManager=new b.CallbackManager(this,["zoomed","panned","centered","extentset","resized","drawn"]);if(k===undefined){this.eventHandlers=[new b.MouseHandler(this),new b.TouchHandler(this)]}else{this.eventHandlers=k;if(k instanceof Array){for(var d=0;d<k.length;d++){k[d].init(this)}}}};b.Map.prototype={parent:null,dimensions:null,projection:null,coordinate:null,tileSize:null,coordLimits:null,layers:null,callbackManager:null,eventHandlers:null,autoSize:null,toString:function(){return"Map(#"+this.parent.id+")"},addCallback:function(c,d){this.callbackManager.addCallback(c,d);return this},removeCallback:function(c,d){this.callbackManager.removeCallback(c,d);return this},dispatchCallback:function(d,c){this.callbackManager.dispatchCallback(d,c);return this},windowResize:function(){if(!this._windowResize){var c=this;this._windowResize=function(d){c.dimensions=new b.Point(c.parent.offsetWidth,c.parent.offsetHeight);c.draw();c.dispatchCallback("resized",[c.dimensions])}}return this._windowResize},setZoomRange:function(d,c){this.coordLimits[0]=this.coordLimits[0].zoomTo(d);this.coordLimits[1]=this.coordLimits[1].zoomTo(c)},zoomBy:function(c){this.coordinate=this.enforceLimits(this.coordinate.zoomBy(c));b.getFrame(this.getRedraw());this.dispatchCallback("zoomed",c);return this},zoomIn:function(){return this.zoomBy(1)},zoomOut:function(){return this.zoomBy(-1)},setZoom:function(c){return this.zoomBy(c-this.coordinate.zoom)},zoomByAbout:function(d,c){var f=this.pointLocation(c);this.coordinate=this.enforceLimits(this.coordinate.zoomBy(d));var e=this.locationPoint(f);this.dispatchCallback("zoomed",d);return this.panBy(c.x-e.x,c.y-e.y)},panBy:function(d,c){this.coordinate.column-=d/this.tileSize.x;this.coordinate.row-=c/this.tileSize.y;this.coordinate=this.enforceLimits(this.coordinate);b.getFrame(this.getRedraw());this.dispatchCallback("panned",[d,c]);return this},panLeft:function(){return this.panBy(100,0)},panRight:function(){return this.panBy(-100,0)},panDown:function(){return this.panBy(0,-100)},panUp:function(){return this.panBy(0,100)},setCenter:function(c){return this.setCenterZoom(c,this.coordinate.zoom)},setCenterZoom:function(c,d){this.coordinate=this.projection.locationCoordinate(c).zoomTo(parseFloat(d)||0);b.getFrame(this.getRedraw());this.dispatchCallback("centered",[c,d]);return this},setExtent:function(q,r){if(q instanceof b.Extent){q=q.toArray()}var u,k;for(var l=0;l<q.length;l++){var m=this.projection.locationCoordinate(q[l]);if(u){u.row=Math.min(u.row,m.row);u.column=Math.min(u.column,m.column);u.zoom=Math.min(u.zoom,m.zoom);k.row=Math.max(k.row,m.row);k.column=Math.max(k.column,m.column);k.zoom=Math.max(k.zoom,m.zoom)}else{u=m.copy();k=m.copy()}}var j=this.dimensions.x+1;var h=this.dimensions.y+1;var n=(k.column-u.column)/(j/this.tileSize.x);var s=Math.log(n)/Math.log(2);var o=u.zoom-(r?s:Math.ceil(s));var p=(k.row-u.row)/(h/this.tileSize.y);var e=Math.log(p)/Math.log(2);var f=u.zoom-(r?e:Math.ceil(e));var c=Math.min(o,f);c=Math.min(c,this.coordLimits[1].zoom);c=Math.max(c,this.coordLimits[0].zoom);var d=(u.row+k.row)/2;var t=(u.column+k.column)/2;var g=u.zoom;this.coordinate=new b.Coordinate(d,t,g).zoomTo(c);this.draw();this.dispatchCallback("extentset",q);return this},setSize:function(c){this.dimensions=new b.Point(c.x,c.y);this.parent.style.width=Math.round(this.dimensions.x)+"px";this.parent.style.height=Math.round(this.dimensions.y)+"px";if(this.autoSize){b.removeEvent(window,"resize",this.windowResize());this.autoSize=false}this.draw();this.dispatchCallback("resized",this.dimensions);return this},coordinatePoint:function(d){if(d.zoom!=this.coordinate.zoom){d=d.zoomTo(this.coordinate.zoom)}var c=new b.Point(this.dimensions.x/2,this.dimensions.y/2);c.x+=this.tileSize.x*(d.column-this.coordinate.column);c.y+=this.tileSize.y*(d.row-this.coordinate.row);return c},pointCoordinate:function(c){var d=this.coordinate.copy();d.column+=(c.x-this.dimensions.x/2)/this.tileSize.x;d.row+=(c.y-this.dimensions.y/2)/this.tileSize.y;return d},locationCoordinate:function(c){return this.projection.locationCoordinate(c)},coordinateLocation:function(c){return this.projection.coordinateLocation(c)},locationPoint:function(c){return this.coordinatePoint(this.locationCoordinate(c))},pointLocation:function(c){return this.coordinateLocation(this.pointCoordinate(c))},getExtent:function(){return new b.Extent(this.pointLocation(new b.Point(0,0)),this.pointLocation(this.dimensions))},extent:function(c,d){if(c){return this.setExtent(c,d)}else{return this.getExtent()}},getCenter:function(){return this.projection.coordinateLocation(this.coordinate)},center:function(c){if(c){return this.setCenter(c)}else{return this.getCenter()}},getZoom:function(){return this.coordinate.zoom},zoom:function(c){if(c!==undefined){return this.setZoom(c)}else{return this.getZoom()}},getLayers:function(){return this.layers.slice()},getLayerAt:function(c){return this.layers[c]},addLayer:function(c){this.layers.push(c);this.parent.appendChild(c.parent);c.map=this;return this},removeLayer:function(d){for(var c=0;c<this.layers.length;c++){if(d==this.layers[c]){this.removeLayerAt(c);break}}return this},setLayerAt:function(c,d){if(c<0||c>=this.layers.length){throw new Error("invalid index in setLayerAt(): "+c)}if(this.layers[c]!=d){if(c<this.layers.length){this.layers[c].destroy()}this.layers[c]=d;this.parent.appendChild(d.parent);d.map=this;b.getFrame(this.getRedraw())}return this},insertLayerAt:function(d,e){if(d<0||d>this.layers.length){throw new Error("invalid index in insertLayerAt(): "+d)}if(d==this.layers.length){this.layers.push(e);this.parent.appendChild(e.parent)}else{var c=this.layers[d];this.parent.insertBefore(e.parent,c.parent);this.layers.splice(d,0,e)}e.map=this;b.getFrame(this.getRedraw());return this},removeLayerAt:function(d){if(d<0||d>=this.layers.length){throw new Error("invalid index in removeLayer(): "+d)}var c=this.layers[d];this.layers.splice(d,1);c.destroy();return this},swapLayersAt:function(d,c){if(d<0||d>=this.layers.length||c<0||c>=this.layers.length){throw new Error("invalid index in swapLayersAt(): "+index)}var g=this.layers[d],e=this.layers[c],f=document.createElement("div");this.parent.replaceChild(f,e.parent);this.parent.replaceChild(e.parent,g.parent);this.parent.replaceChild(g.parent,f);this.layers[d]=e;this.layers[c]=g;return this},enforceZoomLimits:function(f){var d=this.coordLimits;if(d){var e=d[0].zoom;var c=d[1].zoom;if(f.zoom<e){f=f.zoomTo(e)}else{if(f.zoom>c){f=f.zoomTo(c)}}}return f},enforcePanLimits:function(h){var d=this.coordLimits;if(d){h=h.copy();var f=d[0].zoomTo(h.zoom);var c=d[1].zoomTo(h.zoom);var e=this.pointCoordinate(new b.Point(0,0));var g=this.pointCoordinate(this.dimensions);if(c.row-f.row<g.row-e.row){h.row=(c.row+f.row)/2}else{if(e.row<f.row){h.row+=f.row-e.row}else{if(g.row>c.row){h.row-=g.row-c.row}}}if(c.column-f.column<g.column-e.column){h.column=(c.column+f.column)/2}else{if(e.column<f.column){h.column+=f.column-e.column}else{if(g.column>c.column){h.column-=g.column-c.column}}}}return h},enforceLimits:function(c){return this.enforcePanLimits(this.enforceZoomLimits(c))},draw:function(){this.coordinate=this.enforceLimits(this.coordinate);if(this.dimensions.x<=0||this.dimensions.y<=0){if(this.autoSize){var c=this.parent.offsetWidth,e=this.parent.offsetHeight;this.dimensions=new b.Point(c,e);if(c<=0||e<=0){return}}else{return}}for(var d=0;d<this.layers.length;d++){this.layers[d].draw()}this.dispatchCallback("drawn")},_redrawTimer:undefined,requestRedraw:function(){if(!this._redrawTimer){this._redrawTimer=setTimeout(this.getRedraw(),1000)}},_redraw:null,getRedraw:function(){if(!this._redraw){var c=this;this._redraw=function(){c.draw();c._redrawTimer=0}}return this._redraw},destroy:function(){for(var c=0;c<this.layers.length;c++){this.layers[c].destroy()}this.layers=[];this.projection=null;for(var d=0;d<this.eventHandlers.length;d++){this.eventHandlers[d].remove()}if(this.autoSize){b.removeEvent(window,"resize",this.windowResize())}}};if(typeof module!=="undefined"&&module.exports){module.exports={Point:b.Point,Projection:b.Projection,MercatorProjection:b.MercatorProjection,LinearProjection:b.LinearProjection,Transformation:b.Transformation,Location:b.Location,MapProvider:b.MapProvider,TemplatedMapProvider:b.TemplatedMapProvider,Coordinate:b.Coordinate,deriveTransformation:b.deriveTransformation}}})(MM);
57 src/provider.js
@@ -16,8 +16,10 @@
16 16 // these are limits for available *tiles*
17 17 // panning limits will be different (since you can wrap around columns)
18 18 // but if you put Infinity in here it will screw up sourceCoordinate
19   - tileLimits: [ new MM.Coordinate(0,0,0), // top left outer
20   - new MM.Coordinate(1,1,0).zoomTo(18) ], // bottom right inner
  19 + tileLimits: [
  20 + new MM.Coordinate(0,0,0), // top left outer
  21 + new MM.Coordinate(1,1,0).zoomTo(18) // bottom right inner
  22 + ],
21 23
22 24 getTileUrl: function(coordinate) {
23 25 throw "Abstract method not implemented by subclass.";
@@ -27,9 +29,8 @@
27 29 throw "Abstract method not implemented by subclass.";
28 30 },
29 31
30   - releaseTile: function(element) {
31   - // releaseTile is not required
32   - },
  32 + // releaseTile is not required
  33 + releaseTile: function(element) { },
33 34
34 35 // use this to tell MapProvider that tiles only exist between certain zoom levels.
35 36 // should be set separately on Map to restrict interactive zoom/pan ranges
@@ -43,20 +44,24 @@
43 44 // ... you should override this function if you change the tile limits
44 45 // ... see enforce-limits in examples for details
45 46 sourceCoordinate: function(coord) {
46   - var TL = this.tileLimits[0].zoomTo(coord.zoom);
47   - var BR = this.tileLimits[1].zoomTo(coord.zoom);
48   - var vSize = BR.row - TL.row;
49   - if (coord.row < 0 || coord.row >= vSize) {
50   - // it's too high or too low:
51   - return null;
  47 + var TL = this.tileLimits[0].zoomTo(coord.zoom),
  48 + BR = this.tileLimits[1].zoomTo(coord.zoom),
  49 + columnSize = Math.pow(2, coord.zoom),
  50 + wrappedColumn;
  51 +
  52 + if (coord.column < 0) {
  53 + wrappedColumn = (coord.column + columnSize) % columnSize;
  54 + } else {
  55 + wrappedColumn = coord.column % columnSize;
52 56 }
53   - var hSize = BR.column - TL.column;
54   - // assume infinite horizontal scrolling
55   - var wrappedColumn = coord.column % hSize;
56   - while (wrappedColumn < 0) {
57   - wrappedColumn += hSize;
  57 +
  58 + if (coord.row < TL.row || coord.row >= BR.row) {
  59 + return null;
  60 + } else if (wrappedColumn < TL.column || wrappedColumn >= BR.column) {
  61 + return null;
  62 + } else {
  63 + return new MM.Coordinate(coord.row, wrappedColumn, coord.zoom);
58 64 }
59   - return new MM.Coordinate(coord.row, wrappedColumn, coord.zoom);
60 65 }
61 66 };
62 67
@@ -84,15 +89,12 @@
84 89 *
85 90 */
86 91 MM.TemplatedMapProvider = function(template, subdomains) {
87   - var isQuadKey = false;
88   - if (template.match(/{(Q|quadkey)}/)) {
89   - isQuadKey = true;
90   - // replace Microsoft style substitution strings
91   - template = template
92   - .replace('{subdomains}', '{S}')
93   - .replace('{zoom}', '{Z}')
94   - .replace('{quadkey}', '{Q}');
95   - }
  92 + var isQuadKey = template.match(/{(Q|quadkey)}/);
  93 + // replace Microsoft style substitution strings
  94 + if (isQuadKey) template = template
  95 + .replace('{subdomains}', '{S}')
  96 + .replace('{zoom}', '{Z}')
  97 + .replace('{quadkey}', '{Q}');
96 98
97 99 var hasSubdomains = (subdomains &&
98 100 subdomains.length && template.indexOf("{S}") >= 0);
@@ -136,8 +138,7 @@
136 138 },
137 139 getTile: function(coord) {
138 140 return this.getTileUrl(coord);
139   - },
140   - releaseTile: function() { }
  141 + }
141 142 };
142 143
143 144 MM.extend(MM.TemplatedMapProvider, MM.MapProvider);

0 comments on commit c3dfdb9

Please sign in to comment.
Something went wrong with that request. Please try again.