dynmap/web/js/dynmaputils.js

325 lines
9.0 KiB
JavaScript
Raw Normal View History

2011-08-02 17:48:04 +02:00
var DynmapProjection = L.Class.extend({
initialize: function(options) {
L.Util.setOptions(this, options);
},
fromLocationToLatLng: function(location) {
throw "fromLocationToLatLng not implemented";
},
fromLatLngToLocation: function(location) {
return null;
2011-08-02 17:48:04 +02:00
}
});
var DynmapTileLayer = L.TileLayer.extend({
_currentzoom: undefined,
getProjection: function() {
return this.projection;
},
onTileUpdated: function(tile, tileName) {
var src = this.dynmap.getTileUrl(tileName);
tile.attr('src', src);
tile.show();
},
getTileName: function(tilePoint, zoom) {
throw "getTileName not implemented";
},
getTileUrl: function(tilePoint, zoom) {
var tileName = this.getTileName(tilePoint, zoom);
var url = this._cachedTileUrls[tileName];
if (!url) {
this._cachedTileUrls[tileName] = url = this.options.dynmap.getTileUrl(tileName) + '?' + new Date().getUTCMilliseconds();
}
return url;
},
updateNamedTile: function(name) {
var tile = this._namedTiles[name];
delete this._cachedTileUrls[name];
if (tile) {
this.updateTile(tile);
}
},
updateTile: function(tile) {
this._loadTile(tile, tile.tilePoint, this._map.getZoom());
},
// Override to fix loads completing after layer removed
_addTilesFromCenterOut: function(bounds) {
if(this._container == null) // Ignore if we've stopped being active layer
return;
var queue = [],
center = bounds.getCenter();
for (var j = bounds.min.y; j <= bounds.max.y; j++) {
for (var i = bounds.min.x; i <= bounds.max.x; i++) {
if ((i + ':' + j) in this._tiles) { continue; }
queue.push(new L.Point(i, j));
}
}
// load tiles in order of their distance to center
queue.sort(function(a, b) {
return a.distanceTo(center) - b.distanceTo(center);
});
var fragment = document.createDocumentFragment();
this._tilesToLoad = queue.length;
for (var k = 0, len = this._tilesToLoad; k < len; k++) {
this._addTile(queue[k], fragment);
}
this._container.appendChild(fragment);
},
2011-08-02 17:48:04 +02:00
// We should override this, since Leaflet does modulo on tilePoint by default. (https://github.com/CloudMade/Leaflet/blob/master/src/layer/tile/TileLayer.js#L151)
_addTile: function(tilePoint) {
if(this._container == null) // Ignore if we're not active layer
return;
2011-08-02 17:48:04 +02:00
var tilePos = this._getTilePos(tilePoint),
zoom = this._map.getZoom(),
key = tilePoint.x + ':' + tilePoint.y,
name = this.getTileName(tilePoint, zoom);
// create tile
var tile = this._createTile();
tile.tileName = name;
tile.tilePoint = tilePoint;
L.DomUtil.setPosition(tile, tilePos);
this._tiles[key] = tile;
this._namedTiles[name] = tile;
this._loadTile(tile, tilePoint, zoom);
this._container.appendChild(tile);
},
2011-08-10 22:38:46 +02:00
_loadTile: function(tile, tilePoint, zoom) {
var me = this;
tile._layer = this;
function done() {
me._loadingTiles.splice(me._loadingTiles.indexOf(tile), 1);
me._nextLoadTile();
}
tile.onload = function(e) {
me._tileOnLoad.apply(this, [e]);
done();
}
tile.onerror = function() {
me._tileOnError.apply(this);
done();
}
tile.loadSrc = function() {
me._loadingTiles.push(tile);
tile.src = me.getTileUrl(tilePoint, zoom);
};
this._loadQueue.push(tile);
this._nextLoadTile();
},
_nextLoadTile: function() {
if (this._loadingTiles.length > 4) { return; }
2011-08-10 23:32:33 +02:00
var next = this._loadQueue.shift();
2011-08-10 22:38:46 +02:00
if (!next) { return; }
next.loadSrc();
},
2011-08-02 17:48:04 +02:00
_removeOtherTiles: function(bounds) {
var kArr, x, y, key;
for (key in this._tiles) {
if (this._tiles.hasOwnProperty(key)) {
kArr = key.split(':');
x = parseInt(kArr[0], 10);
y = parseInt(kArr[1], 10);
// remove tile if it's out of bounds
if (x < bounds.min.x || x > bounds.max.x || y < bounds.min.y || y > bounds.max.y) {
var tile = this._tiles[key];
if (tile.parentNode === this._container) {
this._container.removeChild(this._tiles[key]);
}
delete this._namedTiles[tile.tileName];
delete this._tiles[key];
}
}
}
},
_updateTileSize: function() {
var newzoom = this._map.getZoom();
if (this._currentzoom !== newzoom) {
var newTileSize = this.calculateTileSize(newzoom);
this._currentzoom = newzoom;
if (newTileSize !== this.options.tileSize) {
this.setTileSize(newTileSize);
}
}
},
_reset: function() {
this._updateTileSize();
this._tiles = {};
this._namedTiles = {};
2011-08-10 22:38:46 +02:00
this._loadQueue = [];
this._loadingTiles = [];
2011-08-02 17:48:04 +02:00
this._cachedTileUrls = {};
this._initContainer();
this._container.innerHTML = '';
},
_update: function() {
this._updateTileSize();
var bounds = this._map.getPixelBounds(),
tileSize = this.options.tileSize;
var nwTilePoint = new L.Point(
Math.floor(bounds.min.x / tileSize),
Math.floor(bounds.min.y / tileSize)),
seTilePoint = new L.Point(
Math.floor(bounds.max.x / tileSize),
Math.floor(bounds.max.y / tileSize)),
tileBounds = new L.Bounds(nwTilePoint, seTilePoint);
this._addTilesFromCenterOut(tileBounds);
if (this.options.unloadInvisibleTiles) {
this._removeOtherTiles(tileBounds);
}
},
/*calculateTileSize: function(zoom) {
return this.options.tileSize;
},*/
calculateTileSize: function(zoom) {
// zoomoutlevel: 0 when izoom > mapzoomin, else mapzoomin - izoom (which ranges from 0 till mapzoomin)
var izoom = this.options.maxZoom - zoom;
var zoominlevel = Math.max(0, this.options.mapzoomin - izoom);
return 128 << zoominlevel;
},
setTileSize: function(tileSize) {
this.options.tileSize = tileSize;
this._tiles = {};
this._createTileProto();
},
updateTileSize: function(zoom) {},
// Some helper functions.
zoomprefix: function(amount) {
return 'zzzzzzzzzzzzzzzzzzzzzz'.substr(0, amount);
},
getTileInfo: function(tilePoint, zoom) {
// zoom: max zoomed in = this.options.maxZoom, max zoomed out = 0
// izoom: max zoomed in = 0, max zoomed out = this.options.maxZoom
// zoomoutlevel: izoom < mapzoomin -> 0, else -> izoom - mapzoomin (which ranges from 0 till mapzoomout)
var izoom = this.options.maxZoom - zoom;
var zoomoutlevel = Math.max(0, izoom - this.options.mapzoomin);
var scale = 1 << zoomoutlevel;
var x = scale*tilePoint.x;
var y = scale*tilePoint.y;
return {
prefix: this.options.prefix,
nightday: (this.options.nightandday && this.options.dynmap.serverday) ? '_day' : '',
scaledx: x >> 5,
scaledy: y >> 5,
zoom: this.zoomprefix(zoomoutlevel),
zoomprefix: (zoomoutlevel==0)?"":(this.zoomprefix(zoomoutlevel)+"_"),
x: x,
y: y
};
}
});
function loadjs(url, completed) {
var script = document.createElement('script');
script.setAttribute('src', url);
script.setAttribute('type', 'text/javascript');
var isloaded = false;
script.onload = function() {
if (isloaded) { return; }
isloaded = true;
completed();
};
// Hack for IE, don't know whether this still applies to IE9.
script.onreadystatechange = function() {
if (script.readyState == 'loaded' || script.readyState == 'complete')
script.onload();
};
(document.head || document.getElementsByTagName('head')[0]).appendChild(script);
}
function loadcss(url, completed) {
var script = document.createElement('link');
script.setAttribute('href', url);
script.setAttribute('rel', 'stylesheet');
var isloaded = false;
if (completed) {
script.onload = function() {
if (isloaded) { return; }
isloaded = true;
completed();
};
// Hack for IE, don't know whether this still applies to IE9.
script.onreadystatechange = function() {
script.onload();
};
}
(document.head || document.getElementsByTagName('head')[0]).appendChild(script);
}
function splitArgs(s) {
var r = s.split(' ');
delete arguments[0];
var obj = {};
var index = 0;
$.each(arguments, function(argumentIndex, argument) {
if (!argumentIndex) { return; }
var value = r[argumentIndex-1];
obj[argument] = value;
});
return obj;
}
function swtch(value, options, defaultOption) {
return (options[value] || defaultOption || function(){})(value);
}
(function( $ ){
$.fn.scrollHeight = function(height) {
return this[0].scrollHeight;
};
})($);
function Location(world, x, y, z) {
this.world = world;
this.x = x;
this.y = y;
this.z = z;
}
function namedReplace(str, obj)
{
var startIndex = 0;
var result = '';
while(true) {
var variableBegin = str.indexOf('{', startIndex);
var variableEnd = str.indexOf('}', variableBegin+1);
if (variableBegin < 0 || variableEnd < 0) {
result += str.substr(startIndex);
break;
}
if (variableBegin < variableEnd) {
var variableName = str.substring(variableBegin+1, variableEnd);
result += str.substring(startIndex, variableBegin);
result += obj[variableName];
} else /* found '{}' */ {
result += str.substring(startIndex, variableBegin-1);
result += '';
}
startIndex = variableEnd+1;
}
return result;
2011-07-21 00:49:52 +02:00
}