@2gis/tiny-map
Advanced tools
Comparing version 0.0.1 to 0.0.2
160
index.js
/** | ||
* A tiny script for displaying a static map with tiles. | ||
* You can't interact with the map, it has only remove method. | ||
* | ||
* @param {HTMLElement} container HTML Element that will be contains the map | ||
* @param {Object} options | ||
* @param {number[]} [options.center] Geographical center of the map, contains two numbers: [longitude, latitude] | ||
* @param {number} [options.zoom] Zoom of the map | ||
* @param {string} [options.tileUrl] URL template for tiles, e.g. //tile{s}.maps.2gis.com/tiles?x={x}&y={y}&z={z} | ||
* @param {string} [options.subdomains='0123'] Subdomains of the tile server, e.g. '0123' | ||
* @param {?number} [options.size] Size of the map container. This is optional parameter, but set it, if you won't cause | ||
* You can't interact with the map. | ||
* / | ||
/** | ||
* @typedef {Object} options | ||
* @property {number[]} center Geographical center of the map, contains two numbers: [longitude, latitude] | ||
* @property {number} zoom Zoom of the map | ||
* @property {string} tileUrl URL template for tiles, e.g. //tile{s}.maps.2gis.com/tiles?x={x}&y={y}&z={z} | ||
* @property {string} subdomains Subdomains of the tile server, e.g. '0123' | ||
* @property {?number} size Size of the map container. This is optional parameter, but set it, if you won't cause | ||
* additional reflow. | ||
*/ | ||
function TinyMap(container, options) { | ||
this._center = options.center; | ||
this._zoom = options.zoom; | ||
this._tileUrl = options.tileUrl; | ||
this._subdomains = options.subdomains || '0123'; | ||
this._size = options.size || [container.offsetWidth, container.offsetHeight]; | ||
container.style.position = 'relative'; | ||
container.style.overflow = 'hidden'; | ||
/** | ||
* @param {HTMLElement} container HTML Element that will be contains the map | ||
* @param {options} options | ||
*/ | ||
function tinyMap(container, options) { | ||
container.style.cssText = 'position:relative;overflow:hidden'; | ||
this._R = 6378137; | ||
this._MAX_LATITUDE = 85.0511287798; | ||
var tileSize = 256; | ||
var R = 6378137; | ||
var maxLat = 85.0511287798; | ||
this.container = container; | ||
this._removed = false; | ||
var pixelCenter = lngLatToPoint(options.center, options.zoom); | ||
var tileSize = 256; | ||
var pixelCenter = this._lngLatToPoint(this._center, this._zoom); | ||
var size = options.size || [container.offsetWidth, container.offsetHeight]; | ||
var halfSize = [size[0] / 2, size[1] / 2]; | ||
var halfSize = [this._size[0] / 2, this._size[1] / 2]; | ||
var minTile = [ | ||
Math.floor((pixelCenter[0] - halfSize[0]) / tileSize), | ||
Math.floor((pixelCenter[1] - halfSize[1]) / tileSize) | ||
(pixelCenter[0] - halfSize[0]) / tileSize | 0, | ||
(pixelCenter[1] - halfSize[1]) / tileSize | 0 | ||
]; | ||
var maxTile = [ | ||
Math.ceil((pixelCenter[0] + halfSize[0]) / tileSize), | ||
Math.ceil((pixelCenter[1] + halfSize[1]) / tileSize) | ||
(pixelCenter[0] + halfSize[0]) / tileSize + 1 | 0, | ||
(pixelCenter[1] + halfSize[1]) / tileSize + 1 | 0 | ||
]; | ||
var centerTile = [ | ||
minTile[0] + Math.floor((maxTile[0] - 1 - minTile[0]) / 2), | ||
minTile[1] + Math.floor((maxTile[1] - 1 - minTile[1]) / 2) | ||
]; | ||
var queue = []; | ||
for (var y = minTile[1]; y < maxTile[1]; y++) { | ||
for (var x = minTile[0]; x < maxTile[0]; x++) { | ||
queue.push([x, y]); | ||
var tile = new Image(); | ||
tile.style.cssText = 'position: absolute;' + | ||
'left:' + (halfSize[0] + x * tileSize - pixelCenter[0] | 0) + 'px;' + | ||
'top:' + (halfSize[1] + y * tileSize - pixelCenter[1] | 0) + 'px;' + | ||
'width:' + tileSize + 'px;' + | ||
'height:' + tileSize + 'px'; | ||
tile.src = getUrl(x, y); | ||
container.appendChild(tile); | ||
} | ||
} | ||
const distance = this._distance; | ||
queue.sort(function(a, b) { | ||
return distance(a, centerTile) - distance(b, centerTile); | ||
}); | ||
function getUrl(x, y) { | ||
return options.tileUrl | ||
.replace('{s}', options.subdomains[Math.abs(x + y) % options.subdomains.length]) | ||
.replace('{x}', x) | ||
.replace('{y}', y) | ||
.replace('{z}', options.zoom); | ||
} | ||
queue.forEach(function(p) { | ||
var _this = this; | ||
var tile = document.createElement('img'); | ||
tile.style.position = 'absolute'; | ||
tile.style.left = Math.floor(halfSize[0] + p[0] * tileSize - pixelCenter[0]) + 'px'; | ||
tile.style.top = Math.floor(halfSize[1] + p[1] * tileSize - pixelCenter[1]) + 'px'; | ||
tile.style.width = tileSize + 'px'; | ||
tile.style.height = tileSize + 'px'; | ||
tile.onload = function() { | ||
if (!_this._removed) { | ||
container.appendChild(tile); | ||
} | ||
}; | ||
tile.src = this._getUrl(p[0], p[1]); | ||
}, this); | ||
} | ||
function lngLatToPoint(lngLat, zoom) { | ||
var point = project(lngLat); | ||
var scale = 256 * Math.pow(2, zoom); | ||
var k = 0.5 / (Math.PI * R); | ||
point[0] = scale * (k * point[0] + 0.5); | ||
point[1] = scale * (-k * point[1] + 0.5); | ||
return point; | ||
} | ||
/** | ||
* Removes the map | ||
*/ | ||
TinyMap.prototype.remove = function() { | ||
var tile; | ||
function project(lngLat) { | ||
var d = Math.PI / 180; | ||
var lat = Math.max(Math.min(maxLat, lngLat[1]), -maxLat); | ||
var sin = Math.sin(lat * d); | ||
while (tile = this.container.firstChild) { | ||
this.container.removeChild(tile); | ||
return [ | ||
R * lngLat[0] * d, | ||
R * Math.log((1 + sin) / (1 - sin)) / 2 | ||
]; | ||
} | ||
this._removed = true; | ||
}; | ||
TinyMap.prototype._distance = function(a, b) { | ||
return Math.sqrt((a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1])); | ||
}; | ||
TinyMap.prototype._getUrl = function(x, y) { | ||
return this._tileUrl | ||
.replace('{s}', this._getSubdomains(x, y)) | ||
.replace('{x}', x) | ||
.replace('{y}', y) | ||
.replace('{z}', this._zoom); | ||
}; | ||
TinyMap.prototype._getSubdomains = function(x, y) { | ||
return this._subdomains[Math.abs(x + y) % this._subdomains.length]; | ||
}; | ||
TinyMap.prototype._lngLatToPoint = function(lngLat, zoom) { | ||
var point = this._project(lngLat); | ||
var scale = 256 * Math.pow(2, zoom); | ||
var k = 0.5 / (Math.PI * this._R); | ||
point[0] = scale * (k * point[0] + 0.5); | ||
point[1] = scale * (-k * point[1] + 0.5); | ||
return point; | ||
}; | ||
TinyMap.prototype._project = function(lngLat) { | ||
var d = Math.PI / 180; | ||
var lat = Math.max(Math.min(this._MAX_LATITUDE, lngLat[1]), -this._MAX_LATITUDE); | ||
var sin = Math.sin(lat * d); | ||
return [ | ||
this._R * lngLat[0] * d, | ||
this._R * Math.log((1 + sin) / (1 - sin)) / 2 | ||
]; | ||
}; | ||
} |
@@ -1,1 +0,1 @@ | ||
function TinyMap(t,i){this._center=i.center,this._zoom=i.zoom,this._tileUrl=i.tileUrl,this._subdomains=i.subdomains||"0123",this._size=i.size||[t.offsetWidth,t.offsetHeight],t.style.position="relative",t.style.overflow="hidden",this._R=6378137,this._MAX_LATITUDE=85.0511287798,this.container=t,this._removed=!1;for(var o=this._lngLatToPoint(this._center,this._zoom),e=[this._size[0]/2,this._size[1]/2],s=[Math.floor((o[0]-e[0])/256),Math.floor((o[1]-e[1])/256)],n=[Math.ceil((o[0]+e[0])/256),Math.ceil((o[1]+e[1])/256)],r=[s[0]+Math.floor((n[0]-1-s[0])/2),s[1]+Math.floor((n[1]-1-s[1])/2)],h=[],a=s[1];a<n[1];a++)for(var l=s[0];l<n[0];l++)h.push([l,a]);const p=this._distance;h.sort(function(t,i){return p(t,r)-p(i,r)}),h.forEach(function(i){var s=this,n=document.createElement("img");n.style.position="absolute",n.style.left=Math.floor(e[0]+256*i[0]-o[0])+"px",n.style.top=Math.floor(e[1]+256*i[1]-o[1])+"px",n.style.width="256px",n.style.height="256px",n.onload=function(){s._removed||t.appendChild(n)},n.src=this._getUrl(i[0],i[1])},this)}TinyMap.prototype.remove=function(){for(var t;t=this.container.firstChild;)this.container.removeChild(t);this._removed=!0},TinyMap.prototype._distance=function(t,i){return Math.sqrt((t[0]-i[0])*(t[0]-i[0])+(t[1]-i[1])*(t[1]-i[1]))},TinyMap.prototype._getUrl=function(t,i){return this._tileUrl.replace("{s}",this._getSubdomains(t,i)).replace("{x}",t).replace("{y}",i).replace("{z}",this._zoom)},TinyMap.prototype._getSubdomains=function(t,i){return this._subdomains[Math.abs(t+i)%this._subdomains.length]},TinyMap.prototype._lngLatToPoint=function(t,i){var o=this._project(t),e=256*Math.pow(2,i),s=.5/(Math.PI*this._R);return o[0]=e*(s*o[0]+.5),o[1]=e*(-s*o[1]+.5),o},TinyMap.prototype._project=function(t){var i=Math.PI/180,o=Math.max(Math.min(this._MAX_LATITUDE,t[1]),-this._MAX_LATITUDE),e=Math.sin(o*i);return[this._R*t[0]*i,this._R*Math.log((1+e)/(1-e))/2]}; | ||
function tinyMap(t,e){function a(t){var e=Math.PI/180,a=Math.max(Math.min(n,t[1]),-n),i=Math.sin(a*e);return[o*t[0]*e,o*Math.log((1+i)/(1-i))/2]}t.style.cssText="position:relative;overflow:hidden";for(var o=6378137,n=85.0511287798,i=function(t,e){var n=a(t),i=256*Math.pow(2,e),r=.5/(Math.PI*o);return n[0]=i*(r*n[0]+.5),n[1]=i*(-r*n[1]+.5),n}(e.center,e.zoom),r=e.size||[t.offsetWidth,t.offsetHeight],s=[r[0]/2,r[1]/2],h=[(i[0]-s[0])/256|0,(i[1]-s[1])/256|0],l=[(i[0]+s[0])/256+1|0,(i[1]+s[1])/256+1|0],p=h[1];p<l[1];p++)for(var c=h[0];c<l[0];c++){var f=new Image;f.style.cssText="position: absolute;left:"+(s[0]+256*c-i[0]|0)+"px;top:"+(s[1]+256*p-i[1]|0)+"px;width:256px;height:256px",f.src=function(t,a){return e.tileUrl.replace("{s}",e.subdomains[Math.abs(t+a)%e.subdomains.length]).replace("{x}",t).replace("{y}",a).replace("{z}",e.zoom)}(c,p),t.appendChild(f)}} |
{ | ||
"name": "@2gis/tiny-map", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"description": "A tiny script for displaying a static map with tiles", | ||
@@ -5,0 +5,0 @@ "author": { |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
6376
70