terom@142: var map_config; terom@142: var map; terom@142: terom@145: L.Control.Link = L.Control.extend({ terom@145: options: { terom@145: position: 'topright', terom@145: url: null, terom@145: }, terom@145: terom@145: onAdd: function (map) { terom@145: var container = L.DomUtil.create('div', 'leaflet-control-link'); terom@145: terom@145: var link = this.link = L.DomUtil.create('a', 'leaflet-control-link-link', container); terom@145: terom@145: map.on('move', this._update, this); terom@145: terom@145: return container; terom@145: }, terom@145: terom@145: onRemove: function (map) { terom@145: map.off('move', this._update, this); terom@145: }, terom@145: terom@145: _update: function (e) { terom@145: var map_center = map.getCenter(); terom@145: var map_zoom = map.getZoom(); terom@145: var size = map.getSize(); terom@145: terom@175: var x = (+map_center.lng) * Math.pow(2, map_config.tile_zoom); terom@175: var y = (-map_center.lat) * Math.pow(2, map_config.tile_zoom); terom@175: var zoom = map_config.tile_zoom - map_zoom; terom@175: terom@145: var state = { terom@145: w: size.x, terom@145: h: size.y, terom@175: x: x >> zoom, terom@175: y: y >> zoom, terom@175: z: zoom terom@145: }; terom@145: terom@145: var url = L.Util.template(this.options.url, L.extend(state, this.options)); terom@145: terom@145: this.link.href = url; terom@145: terom@145: with (state) { terom@145: this.link.innerHTML = w + 'x' + h + ' @ (' + x + ', ' + y + ') @ ' + z; terom@145: } terom@145: }, terom@145: }); terom@145: terom@145: L.control.link = function (options) { terom@145: return new L.Control.Link(options); terom@145: }; terom@145: terom@142: function map_init (_config) { terom@142: map_config = _config; terom@143: terom@143: // pixel coordinates terom@142: var bounds = L.latLngBounds( terom@142: L.latLng(-map_config.image_height, 0), terom@142: L.latLng(0, +map_config.image_width) terom@142: ); terom@142: terom@143: // in zoom-scaled coordinates terom@143: var map_bounds = [ terom@143: [ -(map_config.image_height >> map_config.tile_zoom), 0 ], terom@143: [ 0, +(map_config.image_width >> map_config.tile_zoom) ], terom@143: ]; terom@143: terom@142: map = L.map('map', { terom@142: crs: L .CRS.Simple, terom@142: minZoom: 0, terom@142: maxZoom: map_config.tile_zoom, terom@143: maxBounds: map_bounds terom@142: }); terom@142: terom@142: map.on('move', map_move); terom@142: terom@142: L.tileLayer(map_config.tile_url, { terom@168: tiles_url: map_config.tiles_url, terom@172: tiles_mtime: map_config.tiles_mtime, terom@142: minZoom: 0, terom@142: maxZoom: map_config.tile_zoom, terom@142: tileSize: map_config.tile_size, terom@142: continuousWorld: true, terom@142: noWrap: true, terom@142: zoomReverse: true, terom@142: bounds: bounds terom@142: }).addTo(map); terom@142: terom@145: // controls terom@145: L.control.link({ terom@145: url: map_config.image_url, terom@168: tiles_url: map_config.tiles_url, terom@172: tiles_mtime: map_config.tiles_mtime, terom@145: }).addTo(map); terom@145: terom@142: // set position terom@142: var x = bounds.getCenter().lng; terom@142: var y = -bounds.getCenter().lat; terom@142: var z = 0; terom@142: terom@142: if (document.location.hash) { terom@142: // parse x:y:z tuple terom@142: var pt = document.location.hash.substr(1).split(":"); terom@142: terom@142: // unpack terom@142: if (pt.length) x = parseInt(pt.shift()) || x; terom@142: if (pt.length) y = parseInt(pt.shift()) || y; terom@142: if (pt.length) z = parseInt(pt.shift()) || z; terom@142: } terom@142: terom@142: map_center(x, y, z); terom@142: } terom@142: terom@142: function map_move () { terom@142: var map_center = map.getCenter(); terom@142: var map_zoom = map.getZoom(); terom@142: terom@142: var x = (+map_center.lng) << map_config.tile_zoom; terom@142: var y = (-map_center.lat) << map_config.tile_zoom; terom@142: var z = map_config.tile_zoom - map_zoom; terom@142: terom@142: document.location.hash = x + ":" + y + ":" + z; terom@142: } terom@142: terom@142: /* terom@142: * Position map based on pngtile coordinates terom@142: */ terom@142: function map_center (x, y, z) { terom@142: // translate to lat/lng terom@142: // leaflet seems to base its latlng coordinates on the max zoom level terom@142: var map_center = [ terom@142: -(y >> map_config.tile_zoom), terom@142: +(x >> map_config.tile_zoom), terom@142: ]; terom@142: terom@142: // reversed zoom terom@142: var map_zoom = map_config.tile_zoom - z; terom@142: terom@142: map.setView(map_center, map_zoom); terom@142: } terom@142: