├── screenshots └── .gitkeep ├── index.js ├── .gitignore ├── config.json ├── package.json ├── README.md ├── geojsons └── test.geojson ├── src ├── index.html └── index.js └── LICENSE /screenshots/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | require('./src'); -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | screenshots/*.png 2 | node_modules 3 | .DS_Store -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "center": [52.52, 13.4], 3 | "zoom": 10, 4 | "tileLayerUrl": "https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_nolabels/{z}/{x}/{y}.png" 5 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "geojson-image-creator", 3 | "version": "1.0.0", 4 | "description": "A Node.js script for automatically creating screenshots from Leaflet maps with Geojson layers", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | }, 9 | "keywords": [], 10 | "author": "moklick@webkid.io", 11 | "license": "MIT", 12 | "dependencies": { 13 | "puppeteer": "^1.0.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Leaflet Mapshot 2 | 3 | A script for generating automated screenshots of a local Leaflet map. We used it to create the video in this article https://interaktiv.morgenpost.de/mauerzeichnen-auswertung/. 4 | 5 | ## How does it work? 6 | 7 | When you run the script it uses [`puppeteer`](https://github.com/GoogleChrome/puppeteer) to make screenshots for every GeoJSON file that is under `geojsons`. 8 | You can adjust the `config.json` for changing `tileLayer`, `zoom` and `center`. 9 | 10 | ## Usage 11 | 12 | ``` 13 | npm start 14 | ``` 15 | -------------------------------------------------------------------------------- /geojsons/test.geojson: -------------------------------------------------------------------------------- 1 | { 2 | "type": "Feature", 3 | "properties": {}, 4 | "geometry": { 5 | "type": "Polygon", 6 | "coordinates": [ 7 | [ 8 | [ 9 | 13.2879638671875, 10 | 52.452661893987695 11 | ], 12 | [ 13 | 13.524169921874998, 14 | 52.452661893987695 15 | ], 16 | [ 17 | 13.524169921874998, 18 | 52.55464616298482 19 | ], 20 | [ 21 | 13.2879638671875, 22 | 52.55464616298482 23 | ], 24 | [ 25 | 13.2879638671875, 26 | 52.452661893987695 27 | ] 28 | ] 29 | ] 30 | } 31 | } -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Leaflet Geojson Image Creator 8 | 9 | 10 | 21 | 22 | 23 |
24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 webkid 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const puppeteer = require('puppeteer'); 4 | const { promisify } = require('util'); 5 | 6 | const config = require('../config.json'); 7 | const readDirAsync = promisify(fs.readdir); 8 | const readFileAsync = promisify(fs.readFile); 9 | 10 | const geojsonPath = path.resolve(__dirname, '..', 'geojsons'); 11 | const screenshotPath = path.resolve(__dirname, '..', 'screenshots'); 12 | const htmlPath = `file://${__dirname}/index.html`; 13 | 14 | start(); 15 | 16 | async function start() { 17 | const geojsonPaths = await readDirAsync(geojsonPath); 18 | const browser = await puppeteer.launch(); 19 | const page = await browser.newPage(); 20 | 21 | console.log(`found ${geojsonPaths.length} geojson files at ${geojsonPath}`); 22 | 23 | await page.goto(htmlPath); 24 | await page.evaluate(initMap, config); 25 | 26 | for (let [index, filePath] of geojsonPaths.entries()) { 27 | const geojsonRaw = await readFileAsync(`${geojsonPath}/${filePath}`); 28 | const geojson = JSON.parse(geojsonRaw); 29 | 30 | await page.evaluate(addGeojsonLayer, geojson); 31 | await page.screenshot({ path: `${screenshotPath}/geojson_${index}.png` }); 32 | console.log(`make screenshot for: ${filePath}`); 33 | } 34 | 35 | await browser.close(); 36 | } 37 | 38 | function initMap(config) { 39 | return new Promise((yep, nope) => { 40 | const map = L.map('map').setView(config.center, config.zoom); 41 | const tileLayer = L.tileLayer(config.tileLayerUrl).addTo(map); 42 | 43 | window.map = map; 44 | 45 | tileLayer.on('load', yep); 46 | }); 47 | } 48 | 49 | function addGeojsonLayer(geojson) { 50 | if (typeof geojsonLayer !== 'undefined') { 51 | geojsonLayer.clearLayers(); 52 | } 53 | geojsonLayer = L.geoJSON(geojson).addTo(map); 54 | } --------------------------------------------------------------------------------