diff --git a/.buildpacks b/.buildpacks deleted file mode 100644 index d8610e2..0000000 --- a/.buildpacks +++ /dev/null @@ -1,2 +0,0 @@ -https://github.com/heroku/heroku-buildpack-nodejs.git -https://github.com/jontewks/puppeteer-heroku-buildpack.git \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index eeedde5..34fe7b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +# 3.11.0 + +Improve speed + + - Speed up results: + - Add cache to resolve faster tilesets in sample-server + - Correct default tile url to use https to avoid redirection + - Remove unnecessary network wait. Change it to wait for map load event + - Remove tile fade-in effect to be able to resolve earlier + - Upgrade all dependencies to latest versions + - Removed not-working heroku demo + - Removed validation that broke the /dynamic endpoint + # 3.10.3 Support AWS functions hotfix diff --git a/Dockerfile b/Dockerfile index 4cad752..6e67043 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:14.2 +FROM node:22.0 RUN \ apt-get update \ @@ -11,6 +11,8 @@ RUN \ libasound2 \ libatk-bridge2.0-0 \ libgtk-3-0 \ + libdrm2 \ + libgbm1 \ fonts-wqy-zenhei \ && \ rm -rf /var/lib/apt/lists/* diff --git a/Procfile b/Procfile deleted file mode 100644 index b86420e..0000000 --- a/Procfile +++ /dev/null @@ -1 +0,0 @@ -web: node src/cli.js serve diff --git a/README.md b/README.md index 85bd16b..b4794ff 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Openstreetmap static maps is a nodejs lib, CLI and server open source inspired on google static map service -Here you have a [demo](http://osm-static-maps.herokuapp.com/?geojson=[{"type":"Feature","properties":{"party":"Republican"},"geometry":{"type":"Polygon","coordinates":[[[-104.05,48.99],[-97.22,48.98],[-96.58,45.94],[-104.03,45.94],[-104.05,48.99]]]}},{"type":"Feature","properties":{"party":"Democrat"},"geometry":{"type":"Polygon","coordinates":[[[-109.05,41.00],[-102.06,40.99],[-102.03,36.99],[-109.04,36.99],[-109.05,41.00]]]}}]&height=300&width=300 "Just what I wanted!"). Also a [dynamic version](http://osm-static-maps.herokuapp.com/dynamic?geojson=[{"type":"Feature","properties":{"party":"Republican"},"geometry":{"type":"Polygon","coordinates":[[[-104.05,48.99],[-97.22,48.98],[-96.58,45.94],[-104.03,45.94],[-104.05,48.99]]]}},{"type":"Feature","properties":{"party":"Democrat"},"geometry":{"type":"Polygon","coordinates":[[[-109.05,41.00],[-102.06,40.99],[-102.03,36.99],[-109.04,36.99],[-109.05,41.00]]]}}]&height=300&width=300 "Wow it gets even better!!") of the demo, for testing purposes. +Here you have a [demo](http://localhost:3000/?geojson=[{"type":"Feature","properties":{"party":"Republican"},"geometry":{"type":"Polygon","coordinates":[[[-104.05,48.99],[-97.22,48.98],[-96.58,45.94],[-104.03,45.94],[-104.05,48.99]]]}},{"type":"Feature","properties":{"party":"Democrat"},"geometry":{"type":"Polygon","coordinates":[[[-109.05,41.00],[-102.06,40.99],[-102.03,36.99],[-109.04,36.99],[-109.05,41.00]]]}}]&height=300&width=300 "Just what I wanted!"). Also a [dynamic version](http://localhost:3000/dynamic?geojson=[{"type":"Feature","properties":{"party":"Republican"},"geometry":{"type":"Polygon","coordinates":[[[-104.05,48.99],[-97.22,48.98],[-96.58,45.94],[-104.03,45.94],[-104.05,48.99]]]}},{"type":"Feature","properties":{"party":"Democrat"},"geometry":{"type":"Polygon","coordinates":[[[-109.05,41.00],[-102.06,40.99],[-102.03,36.99],[-109.04,36.99],[-109.05,41.00]]]}}]&height=300&width=300 "Wow it gets even better!!") of the demo, for testing purposes. ## How to use diff --git a/package.json b/package.json index 3c1d4ce..aba2fc6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "osm-static-maps", - "version": "3.10.3", + "version": "3.11.0", "description": "Create a static image of a map with the features you want", "author": "Julian Perelli", "contributors": [ @@ -15,18 +15,18 @@ "url": "http://github.com/jperelli/osm-static-maps.git" }, "dependencies": { - "chrome-aws-lambda": "^5.5.0", - "commander": "^6.2.1", - "express": "4.17.1", - "handlebars": "4.7.6", - "imagemin": "7.0.1", + "chrome-aws-lambda": "^10.1.0", + "commander": "^12.0.0", + "express": "^4.19.2", + "handlebars": "^4.7.8", + "imagemin": "^8.0.1", "imagemin-jpegtran": "7.0.0", "imagemin-optipng": "8.0.0", - "leaflet": "^1.7.1", + "leaflet": "^1.9.4", "leaflet-polylinedecorator": "1.6.0", "mapbox-gl": "^1.13.0", "mapbox-gl-leaflet": "0.0.14", - "puppeteer-core": "^5.5.0" + "puppeteer-core": "^22.7.1" }, "engines": { "node": ">=12" @@ -41,7 +41,10 @@ "osmsm": "./src/cli.js" }, "devDependencies": { - "nodemon": "2.0.6", - "puppeteer": "^5.5.0" + "nodemon": "^3.1.0", + "puppeteer": "^22.7.1" + }, + "overrides": { + "puppeteer-core": "^22.7.1" } -} \ No newline at end of file +} diff --git a/src/cli.js b/src/cli.js index 5333341..21a89b6 100755 --- a/src/cli.js +++ b/src/cli.js @@ -1,6 +1,6 @@ #!/usr/bin/env node -const program = require("commander"); +const { program } = require("commander"); const osmsm = require("./lib"); const package = require("../package.json"); diff --git a/src/lib.js b/src/lib.js index 2af571b..2bbae80 100644 --- a/src/lib.js +++ b/src/lib.js @@ -44,10 +44,11 @@ class Browser { this.browser = null; } async launch() { + const executablePath = await chrome.executablePath return puppeteer.launch({ args: [...chrome.args, "--no-sandbox", "--disable-setuid-sandbox"], defaultViewport: chrome.defaultViewport, - executablePath: await chrome.executablePath, + executablePath, headless: true, ignoreHTTPSErrors: true, }); @@ -57,7 +58,6 @@ class Browser { throw new Error('osm-static-maps is not ready, please wait a few seconds') } if (!this.browser || !this.browser.isConnected()) { - // console.log('NEW BROWSER') this.openingBrowser = true; try { this.browser = await this.launch(); @@ -72,7 +72,6 @@ class Browser { } async getPage() { const browser = await this.getBrowser() - // console.log("NEW PAGE"); return browser.newPage() } } @@ -100,8 +99,51 @@ function httpGet(url) { process.on("warning", (e) => console.warn(e.stack)); + +// add network cache to cache tiles +const cache = {}; +async function configCache(page) { + await page.setRequestInterception(true); + + page.on('request', async (request) => { + const url = request.url(); + if (cache[url] && cache[url].expires > Date.now()) { + await request.respond(cache[url]); + return; + } + request.continue(); + }); + + page.on('response', async (response) => { + const url = response.url(); + const headers = response.headers(); + const cacheControl = headers['cache-control'] || ''; + const maxAgeMatch = cacheControl.match(/max-age=(\d+)/); + const maxAge = maxAgeMatch && maxAgeMatch.length > 1 ? parseInt(maxAgeMatch[1], 10) : 0; + if (maxAge) { + if (cache[url] && cache[url].expires > Date.now()) return; + + let buffer; + try { + buffer = await response.buffer(); + } catch (error) { + // some responses do not contain buffer and do not need to be catched + return; + } + + cache[url] = { + status: response.status(), + headers: response.headers(), + body: buffer, + expires: Date.now() + (maxAge * 1000), + }; + } + }); +} + module.exports = function(options) { return new Promise(function(resolve, reject) { + // TODO: validate options to avoid template injection options = options || {}; options.geojson = (options.geojson && (typeof options.geojson === 'string' ? options.geojson : JSON.stringify(options.geojson))) || ''; options.geojsonfile = options.geojsonfile || ''; @@ -111,7 +153,7 @@ module.exports = function(options) { options.zoom = options.zoom || ''; options.maxZoom = options.maxZoom || (options.vectorserverUrl ? 20 : 17); options.attribution = options.attribution || 'osm-static-maps | © OpenStreetMap contributors'; - options.tileserverUrl = options.tileserverUrl || 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'; + options.tileserverUrl = options.tileserverUrl || 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'; options.vectorserverUrl = options.vectorserverUrl || ''; options.vectorserverToken = options.vectorserverToken || 'no-token'; options.imagemin = options.imagemin || false; @@ -149,19 +191,24 @@ module.exports = function(options) { } const page = await browser.getPage(); + await configCache(page); try { page.on('error', function (err) { reject(err.toString()) }) page.on('pageerror', function (err) { reject(err.toString()) }) - page.on('console', function (msg) { - if (options.haltOnConsoleError && msg.type() === "error") { - reject(JSON.stringify(msg)); - } - }) + if (options.haltOnConsoleError) { + page.on('console', function (msg) { + if (msg.type() === "error") { + reject(JSON.stringify(msg)); + } + }) + } await page.setViewport({ width: Number(options.width), height: Number(options.height) }); - await page.setContent(html, { waitUntil: 'networkidle0', timeout: Number(options.timeout) }); + + await page.setContent(html); + await page.waitForFunction(() => window.mapRendered === true, { timeout: Number(options.timeout) }); let imageBinary = await page.screenshot({ type: options.type || 'png', @@ -205,11 +252,10 @@ module.exports = function(options) { } catch(e) { page.close(); - // console.log("PAGE CLOSED with err" + e); + console.log("PAGE CLOSED with err" + e); throw(e); } page.close(); - // console.log("PAGE CLOSED ok"); })().catch(reject) }); diff --git a/src/server.js b/src/server.js index a45b310..87bcc66 100644 --- a/src/server.js +++ b/src/server.js @@ -33,22 +33,6 @@ app.use((req, res, next) => { next(); }); - -function htmlEscape(text) { - return text.replace(/&/g, '&'). - replace(/ res.sendStatus(200)); const handler = (res, params) => { @@ -71,13 +55,11 @@ app.get("/", (req, res) => handler(res, req.query)); app.post("/", (req, res) => handler(res, req.body)); app.get("/dynamic", (req, res) => { - var sanitized = sanitize(req.query) - handler(res, { ...sanitized, renderToHtml: true }) + handler(res, { ...req.query, renderToHtml: true }) }) app.post("/dynamic", (req, res) => { - var sanitized = sanitize(req.body) - handler(res, { ...sanitized, renderToHtml: true }) + handler(res, { ...req.body, renderToHtml: true }) }) module.exports = http.createServer(app); diff --git a/src/template.html b/src/template.html index 0d9b8e3..59dd68c 100644 --- a/src/template.html +++ b/src/template.html @@ -3,6 +3,9 @@