staticmaps
Version:
A Node.js library for creating map images with markers, polylines, polygons and text.
832 lines (812 loc) • 34.1 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _got = _interopRequireDefault(require("got"));
var _sharp = _interopRequireDefault(require("sharp"));
var _lodash = _interopRequireDefault(require("lodash.find"));
var _lodash2 = _interopRequireDefault(require("lodash.uniqby"));
var _url = _interopRequireDefault(require("url"));
var _lodash3 = _interopRequireDefault(require("lodash.chunk"));
var _modernAsync = require("modern-async");
var _image = _interopRequireDefault(require("./image"));
var _marker = _interopRequireDefault(require("./marker"));
var _polyline = _interopRequireDefault(require("./polyline"));
var _multipolygon = _interopRequireDefault(require("./multipolygon"));
var _circle = _interopRequireDefault(require("./circle"));
var _text = _interopRequireDefault(require("./text"));
var _bound = _interopRequireDefault(require("./bound"));
var _tileserverconfig = _interopRequireDefault(require("./tileserverconfig"));
var _asyncQueue = _interopRequireDefault(require("./helper/asyncQueue"));
var _geo = _interopRequireDefault(require("./helper/geo"));
var RENDER_CHUNK_SIZE = 1000;
var StaticMaps = /*#__PURE__*/function () {
function StaticMaps() {
var _this = this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
(0, _classCallCheck2["default"])(this, StaticMaps);
this.options = options;
this.tileLayers = [];
if (typeof this.options.tileLayers === 'undefined') {
// Pulling from old options for backwards compatibility
var baseLayerOptions = {};
if (this.options.tileUrl) {
baseLayerOptions.tileUrl = this.options.tileUrl;
}
if (this.options.tileSubdomains) {
baseLayerOptions.tileSubdomains = this.options.tileSubdomains;
}
this.tileLayers.push(new _tileserverconfig["default"](baseLayerOptions));
} else {
this.options.tileLayers.forEach(function (layerConfig) {
_this.tileLayers.push(new _tileserverconfig["default"](layerConfig));
});
}
this.width = this.options.width;
this.height = this.options.height;
this.paddingX = this.options.paddingX || 0;
this.paddingY = this.options.paddingY || 0;
this.padding = [this.paddingX, this.paddingY];
this.tileSize = this.options.tileSize || 256;
this.tileRequestTimeout = this.options.tileRequestTimeout;
this.tileRequestHeader = this.options.tileRequestHeader;
this.tileRequestLimit = Number.isFinite(this.options.tileRequestLimit) ? Number(this.options.tileRequestLimit) : 2;
this.reverseY = this.options.reverseY || false;
var zoomRange = this.options.zoomRange || {};
this.zoomRange = {
min: zoomRange.min || 1,
max: this.options.maxZoom || zoomRange.max || 17 // maxZoom
};
// this.maxZoom = this.options.maxZoom; DEPRECATED: use zoomRange.max instead
// # features
this.markers = [];
this.lines = [];
this.multipolygons = [];
this.circles = [];
this.text = [];
this.bounds = [];
// # fields that get set when map is rendered
this.center = [];
this.centerX = 0;
this.centerY = 0;
this.zoom = 0;
}
(0, _createClass2["default"])(StaticMaps, [{
key: "addLine",
value: function addLine(options) {
this.lines.push(new _polyline["default"](options));
}
}, {
key: "addMarker",
value: function addMarker(options) {
this.markers.push(new _marker["default"](options));
}
}, {
key: "addPolygon",
value: function addPolygon(options) {
this.lines.push(new _polyline["default"](options));
}
}, {
key: "addMultiPolygon",
value: function addMultiPolygon(options) {
this.multipolygons.push(new _multipolygon["default"](options));
}
}, {
key: "addCircle",
value: function addCircle(options) {
this.circles.push(new _circle["default"](options));
}
}, {
key: "addBound",
value: function addBound(options) {
this.bounds.push(new _bound["default"](options));
}
}, {
key: "addText",
value: function addText(options) {
this.text.push(new _text["default"](options));
}
/**
* Render static map with all map features that were added to map before
*/
}, {
key: "render",
value: (function () {
var _render = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(center, zoom) {
var _this2 = this;
var maxZoom, extent, centerLon, centerLat;
return _regenerator["default"].wrap(function _callee2$(_context2) {
while (1) switch (_context2.prev = _context2.next) {
case 0:
if (!(!this.lines && !this.markers && !this.multipolygons && !(center && zoom))) {
_context2.next = 2;
break;
}
throw new Error('Cannot render empty map: Add center || lines || markers || polygons.');
case 2:
this.center = center;
this.zoom = zoom || this.calculateZoom();
maxZoom = this.zoomRange.max;
if (maxZoom && this.zoom > maxZoom) this.zoom = maxZoom;
if (center && center.length === 2) {
this.centerX = _geo["default"].lonToX(center[0], this.zoom);
this.centerY = _geo["default"].latToY(center[1], this.zoom);
} else {
// # get extent of all lines
extent = this.determineExtent(this.zoom); // # calculate center point of map
centerLon = (extent[0] + extent[2]) / 2;
centerLat = (extent[1] + extent[3]) / 2;
this.centerX = _geo["default"].lonToX(centerLon, this.zoom);
this.centerY = _geo["default"].latToY(centerLat, this.zoom);
}
this.image = new _image["default"](this.options);
// Await this.drawLayer for each tile layer
_context2.next = 10;
return (0, _modernAsync.mapSeries)(this.tileLayers, /*#__PURE__*/function () {
var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(layer) {
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return _this2.drawLayer(layer);
case 2:
case "end":
return _context.stop();
}
}, _callee);
}));
return function (_x3) {
return _ref.apply(this, arguments);
};
}());
case 10:
_context2.next = 12;
return this.loadMarker();
case 12:
return _context2.abrupt("return", this.drawFeatures());
case 13:
case "end":
return _context2.stop();
}
}, _callee2, this);
}));
function render(_x, _x2) {
return _render.apply(this, arguments);
}
return render;
}()
/**
* calculate common extent of all current map features
*/
)
}, {
key: "determineExtent",
value: function determineExtent(zoom) {
var extents = [];
// Add bbox to extent
if (this.center && this.center.length >= 4) extents.push(this.center);
// add bounds to extent
if (this.bounds.length) {
this.bounds.forEach(function (bound) {
return extents.push(bound.extent());
});
}
// Add polylines and polygons to extent
if (this.lines.length) {
this.lines.forEach(function (line) {
extents.push(line.extent());
});
}
if (this.multipolygons.length) {
this.multipolygons.forEach(function (multipolygon) {
extents.push(multipolygon.extent());
});
}
// Add circles to extent
if (this.circles.length) {
this.circles.forEach(function (circle) {
extents.push(circle.extent());
});
}
// Add marker to extent
for (var i = 0; i < this.markers.length; i++) {
var marker = this.markers[i];
var e = [marker.coord[0], marker.coord[1]];
if (!zoom) {
extents.push([marker.coord[0], marker.coord[1], marker.coord[0], marker.coord[1]]);
continue;
}
// # consider dimension of marker
var ePx = marker.extentPx();
var x = _geo["default"].lonToX(e[0], zoom);
var y = _geo["default"].latToY(e[1], zoom);
extents.push([_geo["default"].xToLon(x - parseFloat(ePx[0]) / this.tileSize, zoom), _geo["default"].yToLat(y + parseFloat(ePx[1]) / this.tileSize, zoom), _geo["default"].xToLon(x + parseFloat(ePx[2]) / this.tileSize, zoom), _geo["default"].yToLat(y - parseFloat(ePx[3]) / this.tileSize, zoom)]);
}
return [Math.min.apply(Math, (0, _toConsumableArray2["default"])(extents.map(function (e) {
return e[0];
}))), Math.min.apply(Math, (0, _toConsumableArray2["default"])(extents.map(function (e) {
return e[1];
}))), Math.max.apply(Math, (0, _toConsumableArray2["default"])(extents.map(function (e) {
return e[2];
}))), Math.max.apply(Math, (0, _toConsumableArray2["default"])(extents.map(function (e) {
return e[3];
})))];
}
/**
* calculate the best zoom level for given extent
*/
}, {
key: "calculateZoom",
value: function calculateZoom() {
for (var z = this.zoomRange.max; z >= this.zoomRange.min; z--) {
var extent = this.determineExtent(z);
var width = (_geo["default"].lonToX(extent[2], z) - _geo["default"].lonToX(extent[0], z)) * this.tileSize;
if (width > this.width - this.padding[0] * 2) continue;
var height = (_geo["default"].latToY(extent[1], z) - _geo["default"].latToY(extent[3], z)) * this.tileSize;
if (height > this.height - this.padding[1] * 2) continue;
return z;
}
return this.zoomRange.min;
}
/**
* transform tile number to pixel on image canvas
*/
}, {
key: "xToPx",
value: function xToPx(x) {
var px = (x - this.centerX) * this.tileSize + this.width / 2;
return Number(Math.round(px));
}
/**
* transform tile number to pixel on image canvas
*/
}, {
key: "yToPx",
value: function yToPx(y) {
var px = (y - this.centerY) * this.tileSize + this.height / 2;
return Number(Math.round(px));
}
}, {
key: "drawLayer",
value: function () {
var _drawLayer = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3(config) {
var xMin, yMin, xMax, yMax, result, x, y, maxTile, tileX, tileY, tileUrl, quadKey, tiles;
return _regenerator["default"].wrap(function _callee3$(_context3) {
while (1) switch (_context3.prev = _context3.next) {
case 0:
if (!(!config || !config.tileUrl)) {
_context3.next = 3;
break;
}
// Early return if we shouldn't draw a base layer
console.log(1);
return _context3.abrupt("return", this.image.draw([]));
case 3:
xMin = Math.floor(this.centerX - 0.5 * this.width / this.tileSize);
yMin = Math.floor(this.centerY - 0.5 * this.height / this.tileSize);
xMax = Math.ceil(this.centerX + 0.5 * this.width / this.tileSize);
yMax = Math.ceil(this.centerY + 0.5 * this.height / this.tileSize);
result = [];
for (x = xMin; x < xMax; x++) {
for (y = yMin; y < yMax; y++) {
// # x and y may have crossed the date line
maxTile = Math.pow(2, this.zoom);
tileX = (x + maxTile) % maxTile;
tileY = (y + maxTile) % maxTile;
if (this.reverseY) tileY = (1 << this.zoom) - tileY - 1;
tileUrl = void 0;
if (config.tileUrl.includes('{quadkey}')) {
quadKey = _geo["default"].tileXYToQuadKey(tileX, tileY, this.zoom);
tileUrl = config.tileUrl.replace('{quadkey}', quadKey);
} else {
tileUrl = config.tileUrl.replace('{z}', this.zoom).replace('{x}', tileX).replace('{y}', tileY);
}
if (config.tileSubdomains.length > 0) {
// replace subdomain with random domain from tileSubdomains array
tileUrl = tileUrl.replace('{s}', config.tileSubdomains[Math.floor(Math.random() * config.tileSubdomains.length)]);
}
result.push({
url: tileUrl,
box: [this.xToPx(x), this.yToPx(y), this.xToPx(x + 1), this.yToPx(y + 1)]
});
}
}
_context3.next = 11;
return this.getTiles(result);
case 11:
tiles = _context3.sent;
return _context3.abrupt("return", this.image.draw(tiles.filter(function (v) {
return v.success;
}).map(function (v) {
return v.tile;
})));
case 13:
case "end":
return _context3.stop();
}
}, _callee3, this);
}));
function drawLayer(_x4) {
return _drawLayer.apply(this, arguments);
}
return drawLayer;
}()
}, {
key: "drawSVG",
value: function () {
var _drawSVG = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4(features, svgFunction) {
var chunks, baseImage, imageMetadata, processedChunks;
return _regenerator["default"].wrap(function _callee4$(_context4) {
while (1) switch (_context4.prev = _context4.next) {
case 0:
if (features.length) {
_context4.next = 2;
break;
}
return _context4.abrupt("return");
case 2:
// Chunk for performance
chunks = (0, _lodash3["default"])(features, RENDER_CHUNK_SIZE);
baseImage = (0, _sharp["default"])(this.image.image);
_context4.next = 6;
return baseImage.metadata();
case 6:
imageMetadata = _context4.sent;
processedChunks = chunks.map(function (c) {
var svg = "\n <svg\n width=\"".concat(imageMetadata.width, "px\"\n height=\"").concat(imageMetadata.height, "px\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\">\n ").concat(c.map(function (f) {
return svgFunction(f);
}).join('\n'), "\n </svg>\n ");
return {
input: Buffer.from(svg),
top: 0,
left: 0
};
});
_context4.next = 10;
return baseImage.composite(processedChunks).toBuffer();
case 10:
this.image.image = _context4.sent;
case 11:
case "end":
return _context4.stop();
}
}, _callee4, this);
}));
function drawSVG(_x5, _x6) {
return _drawSVG.apply(this, arguments);
}
return drawSVG;
}()
/**
* Render a circle to SVG
*/
}, {
key: "circleToSVG",
value: function circleToSVG(circle) {
var latCenter = circle.coord[1];
var radiusInPixel = _geo["default"].meterToPixel(circle.radius, this.zoom, latCenter);
var x = this.xToPx(_geo["default"].lonToX(circle.coord[0], this.zoom));
var y = this.yToPx(_geo["default"].latToY(circle.coord[1], this.zoom));
return "\n <circle\n cx=\"".concat(x, "\"\n cy=\"").concat(y, "\"\n r=\"").concat(radiusInPixel, "\"\n style=\"fill-rule: inherit;\"\n stroke=\"").concat(circle.color, "\"\n fill=\"").concat(circle.fill, "\"\n stroke-width=\"").concat(circle.width, "\"\n />\n ");
}
/**
* Render text to SVG
*/
}, {
key: "textToSVG",
value: function textToSVG(text) {
var mapcoords = [this.xToPx(_geo["default"].lonToX(text.coord[0], this.zoom)) - text.offset[0], this.yToPx(_geo["default"].latToY(text.coord[1], this.zoom)) - text.offset[1]];
return "\n <text\n x=\"".concat(mapcoords[0], "\"\n y=\"").concat(mapcoords[1], "\"\n style=\"fill-rule: inherit; font-family: ").concat(text.font, ";\"\n font-size=\"").concat(text.size, "pt\"\n stroke=\"").concat(text.color, "\"\n fill=\"").concat(text.fill ? text.fill : 'none', "\"\n stroke-width=\"").concat(text.width, "\"\n text-anchor=\"").concat(text.anchor, "\"\n >\n ").concat(text.text, "\n </text>\n ");
}
/**
* Render MultiPolygon to SVG
*/
}, {
key: "multiPolygonToSVG",
value: function multiPolygonToSVG(multipolygon) {
var _this3 = this;
var shapeArrays = multipolygon.coords.map(function (shape) {
return shape.map(function (coord) {
return [_this3.xToPx(_geo["default"].lonToX(coord[0], _this3.zoom)), _this3.yToPx(_geo["default"].latToY(coord[1], _this3.zoom))];
});
});
var pathArrays = shapeArrays.map(function (points) {
var startPoint = points.shift();
var pathParts = ["M ".concat(startPoint[0], " ").concat(startPoint[1])].concat((0, _toConsumableArray2["default"])(points.map(function (p) {
return "L ".concat(p[0], " ").concat(p[1]);
})), ['Z']);
return pathParts.join(' ');
});
return "<path\n d=\"".concat(pathArrays.join(' '), "\"\n style=\"fill-rule: inherit;\"\n stroke=\"").concat(multipolygon.color, "\"\n fill=\"").concat(multipolygon.fill ? multipolygon.fill : 'none', "\"\n stroke-width=\"").concat(multipolygon.width, "\"/>");
}
/**
* Render Polyline to SVG
*/
}, {
key: "lineToSVG",
value: function lineToSVG(line) {
var _this4 = this;
var points = line.coords.map(function (coord) {
return [_this4.xToPx(_geo["default"].lonToX(coord[0], _this4.zoom)), _this4.yToPx(_geo["default"].latToY(coord[1], _this4.zoom))];
});
return "<".concat(line.type === 'polyline' ? 'polyline' : 'polygon', "\n style=\"fill-rule: inherit;\"\n points=\"").concat(points.join(' '), "\"\n stroke=\"").concat(line.color, "\"\n fill=\"").concat(line.fill ? line.fill : 'none', "\"\n stroke-width=\"").concat(line.width, "\"/>");
}
/**
* Draw markers to the basemap
*/
}, {
key: "drawMarkers",
value: function drawMarkers() {
var _this5 = this;
var queue = [];
this.markers.forEach(function (marker) {
queue.push( /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee5() {
var top, left, markerInstance, metadata, resizeData;
return _regenerator["default"].wrap(function _callee5$(_context5) {
while (1) switch (_context5.prev = _context5.next) {
case 0:
top = Math.round(marker.position[1]);
left = Math.round(marker.position[0]);
if (!(top < 0 || left < 0 || top > _this5.height || left > _this5.width)) {
_context5.next = 4;
break;
}
return _context5.abrupt("return");
case 4:
_context5.next = 6;
return (0, _sharp["default"])(marker.imgData);
case 6:
markerInstance = _context5.sent;
if (!(marker.width === null || marker.height === null)) {
_context5.next = 16;
break;
}
_context5.next = 10;
return markerInstance.metadata();
case 10:
metadata = _context5.sent;
if (!(Number.isFinite(metadata.width) && Number.isFinite(metadata.height))) {
_context5.next = 15;
break;
}
marker.setSize(metadata.width, metadata.height);
_context5.next = 16;
break;
case 15:
throw new Error("Cannot detectimage size of marker ".concat(marker.img, ". Please define manually!"));
case 16:
if (!(marker.drawWidth !== marker.width || marker.drawHeight !== marker.height)) {
_context5.next = 22;
break;
}
resizeData = {
fit: marker.resizeMode
};
if (marker.drawWidth !== marker.width) {
resizeData.width = marker.drawWidth;
}
if (marker.drawHeight !== marker.height) {
resizeData.height = marker.drawHeight;
}
_context5.next = 22;
return markerInstance.resize(resizeData);
case 22:
_context5.t0 = (0, _sharp["default"])(_this5.image.image);
_context5.next = 25;
return markerInstance.toBuffer();
case 25:
_context5.t1 = _context5.sent;
_context5.t2 = top;
_context5.t3 = left;
_context5.t4 = {
input: _context5.t1,
top: _context5.t2,
left: _context5.t3
};
_context5.t5 = [_context5.t4];
_context5.next = 32;
return _context5.t0.composite.call(_context5.t0, _context5.t5).toBuffer();
case 32:
_this5.image.image = _context5.sent;
case 33:
case "end":
return _context5.stop();
}
}, _callee5);
})));
});
return (0, _asyncQueue["default"])(queue);
}
/**
* Draw all features to the basemap
*/
}, {
key: "drawFeatures",
value: (function () {
var _drawFeatures = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee6() {
var _this6 = this;
return _regenerator["default"].wrap(function _callee6$(_context6) {
while (1) switch (_context6.prev = _context6.next) {
case 0:
_context6.next = 2;
return this.drawSVG(this.lines, function (c) {
return _this6.lineToSVG(c);
});
case 2:
_context6.next = 4;
return this.drawSVG(this.multipolygons, function (c) {
return _this6.multiPolygonToSVG(c);
});
case 4:
_context6.next = 6;
return this.drawMarkers();
case 6:
_context6.next = 8;
return this.drawSVG(this.text, function (c) {
return _this6.textToSVG(c);
});
case 8:
_context6.next = 10;
return this.drawSVG(this.circles, function (c) {
return _this6.circleToSVG(c);
});
case 10:
case "end":
return _context6.stop();
}
}, _callee6, this);
}));
function drawFeatures() {
return _drawFeatures.apply(this, arguments);
}
return drawFeatures;
}()
/**
* Preloading the icon image
*/
)
}, {
key: "loadMarker",
value: function loadMarker() {
var _this7 = this;
return new Promise(function (resolve, reject) {
if (!_this7.markers.length) resolve(true);
var icons = (0, _lodash2["default"])(_this7.markers.map(function (m) {
return {
file: m.img
};
}), 'file');
var count = 1;
icons.forEach( /*#__PURE__*/function () {
var _ref3 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee7(ico) {
var icon, isUrl, img;
return _regenerator["default"].wrap(function _callee7$(_context7) {
while (1) switch (_context7.prev = _context7.next) {
case 0:
icon = ico;
isUrl = !!_url["default"].parse(icon.file).hostname;
_context7.prev = 2;
if (!isUrl) {
_context7.next = 12;
break;
}
_context7.next = 6;
return _got["default"].get({
https: {
rejectUnauthorized: false
},
url: icon.file,
responseType: 'buffer'
});
case 6:
img = _context7.sent;
_context7.next = 9;
return (0, _sharp["default"])(img.body).toBuffer();
case 9:
icon.data = _context7.sent;
_context7.next = 15;
break;
case 12:
_context7.next = 14;
return (0, _sharp["default"])(icon.file).toBuffer();
case 14:
icon.data = _context7.sent;
case 15:
_context7.next = 20;
break;
case 17:
_context7.prev = 17;
_context7.t0 = _context7["catch"](2);
reject(_context7.t0);
case 20:
if (count++ === icons.length) {
// Pre loaded all icons
_this7.markers.forEach(function (mark) {
var marker = mark;
marker.position = [_this7.xToPx(_geo["default"].lonToX(marker.coord[0], _this7.zoom)) - marker.offset[0], _this7.yToPx(_geo["default"].latToY(marker.coord[1], _this7.zoom)) - marker.offset[1]];
var imgData = (0, _lodash["default"])(icons, {
file: marker.img
});
marker.set(imgData.data);
});
resolve(true);
}
case 21:
case "end":
return _context7.stop();
}
}, _callee7, null, [[2, 17]]);
}));
return function (_x7) {
return _ref3.apply(this, arguments);
};
}());
});
}
/**
* Fetching tile from endpoint
*/
}, {
key: "getTile",
value: (function () {
var _getTile = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee8(data) {
var options, res, body, headers, contentType;
return _regenerator["default"].wrap(function _callee8$(_context8) {
while (1) switch (_context8.prev = _context8.next) {
case 0:
options = {
url: data.url,
responseType: 'buffer',
// resolveWithFullResponse: true,
headers: this.tileRequestHeader || {},
timeout: this.tileRequestTimeout
};
_context8.prev = 1;
_context8.next = 4;
return _got["default"].get(options);
case 4:
res = _context8.sent;
body = res.body, headers = res.headers;
contentType = headers['content-type'];
if (contentType.startsWith('image/')) {
_context8.next = 9;
break;
}
throw new Error('Tiles server response with wrong data');
case 9:
return _context8.abrupt("return", {
success: true,
tile: {
url: data.url,
box: data.box,
body: body
}
});
case 12:
_context8.prev = 12;
_context8.t0 = _context8["catch"](1);
return _context8.abrupt("return", {
success: false,
error: _context8.t0
});
case 15:
case "end":
return _context8.stop();
}
}, _callee8, this, [[1, 12]]);
}));
function getTile(_x8) {
return _getTile.apply(this, arguments);
}
return getTile;
}()
/**
* Fetching tiles and limit concurrent connections
*/
)
}, {
key: "getTiles",
value: (function () {
var _getTiles = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee11(baseLayers) {
var _this8 = this;
var limit, aQueue, tiles, _loop, i, j, tilePromises;
return _regenerator["default"].wrap(function _callee11$(_context12) {
while (1) switch (_context12.prev = _context12.next) {
case 0:
limit = this.tileRequestLimit; // Limit concurrent connections to tiles server
// https://operations.osmfoundation.org/policies/tiles/#technical-usage-requirements
if (!Number(limit)) {
_context12.next = 14;
break;
}
aQueue = [];
tiles = [];
_loop = /*#__PURE__*/_regenerator["default"].mark(function _loop() {
var chunks, sQueue;
return _regenerator["default"].wrap(function _loop$(_context11) {
while (1) switch (_context11.prev = _context11.next) {
case 0:
chunks = baseLayers.slice(i, i + limit);
sQueue = [];
aQueue.push( /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee10() {
return _regenerator["default"].wrap(function _callee10$(_context10) {
while (1) switch (_context10.prev = _context10.next) {
case 0:
chunks.forEach(function (r) {
sQueue.push((0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee9() {
var tile;
return _regenerator["default"].wrap(function _callee9$(_context9) {
while (1) switch (_context9.prev = _context9.next) {
case 0:
_context9.next = 2;
return _this8.getTile(r);
case 2:
tile = _context9.sent;
tiles.push(tile);
case 4:
case "end":
return _context9.stop();
}
}, _callee9);
}))());
});
_context10.next = 3;
return Promise.all(sQueue);
case 3:
case "end":
return _context10.stop();
}
}, _callee10);
})));
case 3:
case "end":
return _context11.stop();
}
}, _loop);
});
i = 0, j = baseLayers.length;
case 6:
if (!(i < j)) {
_context12.next = 11;
break;
}
return _context12.delegateYield(_loop(), "t0", 8);
case 8:
i += limit;
_context12.next = 6;
break;
case 11:
_context12.next = 13;
return (0, _asyncQueue["default"])(aQueue);
case 13:
return _context12.abrupt("return", tiles);
case 14:
// Do not limit concurrent connections at all
tilePromises = [];
baseLayers.forEach(function (r) {
tilePromises.push(_this8.getTile(r));
});
return _context12.abrupt("return", Promise.all(tilePromises));
case 17:
case "end":
return _context12.stop();
}
}, _callee11, this);
}));
function getTiles(_x9) {
return _getTiles.apply(this, arguments);
}
return getTiles;
}())
}]);
return StaticMaps;
}();
var _default = exports["default"] = StaticMaps;
module.exports = StaticMaps;