{"id":13426353,"url":"https://github.com/StephanGeorg/staticmaps","last_synced_at":"2025-03-15T21:31:06.849Z","repository":{"id":16004072,"uuid":"79118046","full_name":"StephanGeorg/staticmaps","owner":"StephanGeorg","description":"A Node.js library for creating map images with markers, polylines, polygons and text.","archived":false,"fork":false,"pushed_at":"2024-02-06T10:52:10.000Z","size":18510,"stargazers_count":171,"open_issues_count":17,"forks_count":50,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-13T08:11:15.410Z","etag":null,"topics":["markers","openstreetmap","polygons","polyline","staticmap","staticmaps"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/StephanGeorg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2017-01-16T12:53:24.000Z","updated_at":"2025-02-25T15:16:45.000Z","dependencies_parsed_at":"2024-03-08T03:46:50.126Z","dependency_job_id":null,"html_url":"https://github.com/StephanGeorg/staticmaps","commit_stats":null,"previous_names":[],"tags_count":37,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StephanGeorg%2Fstaticmaps","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StephanGeorg%2Fstaticmaps/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StephanGeorg%2Fstaticmaps/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StephanGeorg%2Fstaticmaps/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StephanGeorg","download_url":"https://codeload.github.com/StephanGeorg/staticmaps/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243792343,"owners_count":20348626,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["markers","openstreetmap","polygons","polyline","staticmap","staticmaps"],"created_at":"2024-07-31T00:01:32.565Z","updated_at":"2025-03-15T21:31:06.379Z","avatar_url":"https://github.com/StephanGeorg.png","language":"JavaScript","readme":"# StaticMaps [![npm version](https://badge.fury.io/js/staticmaps.svg)](https://badge.fury.io/js/staticmaps)\nA Node.js library for creating map images with markers, polylines, polygons and text. This library is a JavaScript implementation of [Static Map](https://github.com/komoot/staticmap).\n\n![Map with polyline](https://stephangeorg.github.io/staticmaps/sample/polyline.png?raw=true=800x280)\n\n## Prerequisites\n\nImage manipulation is based on **[Sharp](https://sharp.pixelplumbing.com/)**. Pre-compiled [libvips](https://github.com/libvips/libvips) binaries for sharp are provided for use with Node.js versions 14+ on macOS (x64, ARM64), Linux (x64, ARM64) and Windows (x64, x86) platforms. For other OS or using with **Heroku, Docker, AWS Lambda** please refer to [sharp installation instructions](https://sharp.pixelplumbing.com/install).\n\n## Releases\n\nVersion           | sharp            | libvips | Node.js (pre-compiled)\n----------------- | ---------------- | ------- | -------------\n1.13.1+           | 0.33.2           | 8.15.1  | 18.17.0+\n1.12.0            | 0.31.3           | 8.13.3  | 14.15.0+\n1.11.1            | 0.31.3           | 8.13.3  | 14.15.0+\n1.10.0            | 0.30.7           | 8.12.2  | 12.13.0+\n\n[Changelog](https://github.com/StephanGeorg/staticmaps/releases)\n\n## Installation\n\n```bash\nnpm i staticmaps\n```\n\n## Getting Started\n\n### Initialization ###\n```javascript\nimport StaticMaps from 'staticmaps';\n```\n```javascript\nconst options = {\n  width: 600,\n  height: 400\n};\nconst map = new StaticMaps(options);\n```\n#### Map options\n\nParameter           | Default             | Description\n------------------- | ------------------- | -------------\nwidth               | Required            | Width of the output image in px\nheight              | Required            | Height of the output image in px\npaddingX            | 0                   | (optional) Minimum distance in px between map features and map border\npaddingY            | 0                   | (optional) Minimum distance in px between map features and map border\ntileUrl             |                     | (optional) Tile server URL for the map base layer or `null` for empty base layer. `{x},{y},{z}` or `{quadkey}` supported.\ntileSubdomains      | []                  | (optional) Subdomains of tile server, usage `['a', 'b', 'c']`\ntileLayers          | []                  | (optional) Tile layers to use, usage `[{tileUrl: ..., tileSubdomains: ...}, {tileUrl: ..., tileSubdomains: ...}]` (replaces `tileUrl` and `tileSubdomains` if set)\ntileSize            | 256                 | (optional) Tile size in pixel\ntileRequestTimeout  |                     | (optional) Timeout for the tiles request\ntileRequestHeader   | {}                  | (optional) Additional headers for the tiles request (default: {})\ntileRequestLimit    | 2                   | (optional) Limit concurrent connections to the tiles server\nzoomRange           | { min: 1, max: 17 } | (optional) Defines the range of zoom levels to try\nmaxZoom             |                     | (optional) DEPRECATED: Use zoomRange.max instead: forces zoom to stay at least this far from the surface, useful for tile servers that error on high levels\nreverseY            | false               | (optional) If true, reverse the y index of the tiles to match the TMS naming format\n\n### Methods\n\nMethod              |  Description\n------------------- | -------------\n[addMarker](#addmarker-options)           | Adds a marker to the map\n[addLine](#addline-options)             | Adds a polyline to the map\n[addPolygon](#addpolygon-options)          | Adds a polygon to the map\n[addMultiPolygon](#addmultipolygon-options)     | Adds a multipolygon to the map\n[addCircle](#addcircle-options)           | Adds a circle to the map\n[addText](#addtext-options)             | Adds text to the map\n[render](#render-center-zoom)              | Renders the map and added features\n[image.save](#imagesave-filename-outputoptions)          | Saves the map image to a file \n[image.buffer](#imagebuffer-mime-outputoptions)        | Saves the map image to a buffer\n\n#### addMarker (options)\nAdds a marker to the map.\n##### Marker options\nParameter           | Default   | Description\n------------------- | --------- | -------------\ncoord               | Required  | Coordinates of the marker ([Lng, Lat])\nimg                 | Required  | Marker image path or URL\nheight              | Required  | Height of marker image in px\nwidth               | Required  | Width of marker image in px\ndrawHeight          | height    | (optional) Resize marker image to height in px\ndrawWidth           | width     | (optional) Resize marker image to width in px\nresizeMode          | cover     | (optional) Applied resize method if needed. See: [https://sharp.pixelplumbing.com/api-resize]\noffsetX             | width/2   | (optional) X offset of the marker image in px\noffsetY             | height    | (optional) Y offset of the marker image in px\n##### Usage example\n```javascript\nconst marker = {\n  img: `${__dirname}/marker.png`, // can also be a URL\n  offsetX: 24,\n  offsetY: 48,\n  width: 48,\n  height: 48,\n  coord : [13.437524,52.4945528]\n};\nmap.addMarker(marker);\n```\n***\n#### addLine (options)\nAdds a polyline to the map.\n##### Polyline options\nParameter           | Default   | Description\n------------------- | --------- |-------------\ncoords              | Required  | Coordinates of the polyline ([[Lng, Lat], ... ,[Lng, Lat]])\ncolor               | #000000BB | (optional) Stroke color of the polyline\nwidth               | 3         | (optional) Stroke width of the polyline\n##### Usage example\n```javascript\n  const polyline = {\n    coords: [\n      [13.399259,52.482659],\n      [13.387849,52.477144],\n      [13.40538,52.510632]\n    ],\n    color: '#0000FFBB',\n    width: 3\n  };\n\n  map.addLine(polyline);\n```\n***\n\n#### addPolygon (options)\nAdds a polygon to the map. Polygon is the same as a polyline but first and last coordinate are equal.\n```\nmap.addPolygon(options);\n```\n##### Polygon options\nParameter           | Default   | Description\n------------------- | --------- | -------------\ncoords              | Required  | Coordinates of the polygon ([[Lng, Lat], ... ,[Lng, Lat]])\ncolor               | #000000BB | (optional) Stroke color of the polygon  \nwidth               | 3         | (optional) Stroke width of the polygon\nfill                | #000000BB | (optional) Fill color of the polygon\n##### Usage example\n```javascript\n  const polygon = {\n    coords: [\n      [13.399259,52.482659],\n      [13.387849,52.477144],\n      [13.40538,52.510632],\n      [13.399259,52.482659]\n    ],\n    color: '#0000FFBB',\n    width: 3\n  };\n\n  map.addPolygon(polygon);\n```\n***\n\n#### addMultiPolygon (options)\nAdds a multipolygon to the map.\n```\nmap.addMultiPolygon(options);\n```\n##### Multipolygon options\nParameter           | Default   | Description\n------------------- | --------- | -------------\ncoords              | Required  | Coordinates of the multipolygon ([[Lng, Lat], ... ,[Lng, Lat]])\ncolor               | #000000BB | (optional) Stroke color of the multipolygon  \nwidth               | 3         | (optional) Stroke width of the multipolygon\nfill                | #000000BB | (optional) Fill color of the multipolygon\n##### Usage example\n```javascript\n  const multipolygon = {\n    coords: [\n      [\n        [-89.9619685, 41.7792032],\n        [-89.959505, 41.7792084],\n        [-89.9594928, 41.7827904],\n        [-89.9631906, 41.7827815],\n        [-89.9632678, 41.7821559],\n        [-89.9634801, 41.7805341],\n        [-89.9635341, 41.780109],\n        [-89.9635792, 41.7796834],\n        [-89.9636183, 41.7792165],\n        [-89.9619685, 41.7792032],\n      ],\n      [\n        [-89.9631647, 41.7809413],\n        [-89.9632927, 41.7809487],\n        [-89.9631565, 41.781985],\n        [-89.9622404, 41.7819137],\n        [-89.9623616, 41.780997],\n        [-89.963029, 41.7810114],\n        [-89.9631647, 41.7809413],\n      ],\n    ],\n    color: '#0000FFBB',\n    width: 3\n  };\n\n  map.addMultiPolygon(multipolygon);\n```\n***\n\n#### addCircle (options)\nAdds a circle to the map.\n```\nmap.addCircle(options);\n```\n##### Circle options\nParameter           | Default   | Description\n------------------- | --------- | -------------\ncoord               | Required  | Coordinate of center of circle\nradius              | Required  | Circle radius in meter\ncolor               | #000000BB | (optional) Stroke color of the circle  \nwidth               | 3         | (optional) Stroke width of the circle\nfill                | #AA0000BB | (optional) Fill color of the circle\n##### Usage example\n```javascript\n  const circle = {\n    coord: [13.01, 51.98],\n    radius: 500,\n    fill: '#000000',\n    width: 0,\n  };\n\n  map.addCircle(circle);\n```\n***\n\n#### addText (options)\nAdds text to the map.\n```\nmap.addText(options)\n```\n##### Text options\nParameter         | Default   | Description\n----------------- | --------- | --------------\ncoord             | Required  | Coordinates of the text ([x, y])\ntext              | Required  | The text to render\ncolor             | #000000BB | (optional) Stroke color of the text\nwidth             | 1px       | (optional) Stroke width of the text\nfill              | #000000   | (optional) Fill color of the text\nsize              | 12        | (optional) Font-size of the text\nfont              | Arial     | (optional) Font-family of the text\nanchor            | start     | (optional) Anchor of the text (`start`, `middle` or `end`)\noffsetX           | 0         | (optional) X offset of the text in px.\noffsetY           | 0         | (optional) Y offset of the text in px.\n\n##### Usage example\n```javascript\n  const text = {\n    coord: [13.437524, 52.4945528],\n    text: 'My Text',\n    size: 50,\n    width: 1,\n    fill: '#000000',\n    color: '#ffffff',\n    font: 'Calibri',\n    anchor: 'middle'\n  };\n\n  map.addText(text);\n```\n\n***\n\n#### render (center, zoom)\nRenders the map.\n```\nmap.render();\n```\n##### Render options\nParameter           | Default   | Description\n------------------- | --------- | -------------\ncenter              |           | (optional) Set center of map to a specific coordinate ([Lng, Lat])\nzoom                |           | (optional) Set a specific zoom level.      \n\n***\n\n#### image.save (fileName, [outputOptions])\nSaves the image to a file in `fileName`.\n```\nmap.image.save('my-staticmap-image.png', { compressionLevel: 9 });\n```\n##### Arguments\nParameter           | Default     | Description\n------------------- | ----------- | -------------\nfileName            | output.png  | Name of the output file. Specify output format (png, jpg, webp) by adding file extension.\noutputOptions       |             | (optional) Output options set for [sharp](http://sharp.pixelplumbing.com/en/stable/api-output/#png)\n\nThe `outputOptions` replaces the deprectated `quality` option. For Backwards compatibility `quality` still works but will be overwritten with `outputOptions.quality`.\n\n\n##### Returns\n```\n\u003cPromise\u003e\n```\n~~If callback is undefined it return a Promise.~~ DEPRECATED\n\n***\n\n#### image.buffer (mime, [outputOptions])\nSaves the image to a buffer.\n```\nmap.image.buffer('image/jpeg', { quality: 75 });\n```\n##### Arguments\nParameter           | Default     | Description\n------------------- | ----------- | -------------\nmime                | image/png   | Mime type(`image/png`, `image/jpg` or `image/webp`) of the output buffer\noutputOptions       | {}          | (optional) Output options set for [sharp](http://sharp.pixelplumbing.com/en/stable/api-output/#png)\n\nThe `outputOptions` replaces the deprectated `quality` option. For Backwards compatibility `quality` still works but will be overwritten with `outputOptions.quality`.\n\n##### Returns\n```\n\u003cPromise\u003e\n```\n~~If callback is undefined it return a Promise.~~ DEPRECATED\n\n## Usage Examples\n\n### Simple map w/ zoom and center\n```javascript\nconst zoom = 13;\nconst center = [13.437524,52.4945528];\n\nawait map.render(center, zoom);\nawait map.image.save('center.png');\n\n```\n#### Output\n![Map with zoom and center](https://stephangeorg.github.io/staticmaps/sample/center.png)\n\n### Simple map with bounding box\n\nIf specifying a bounding box instead of a center, the optimal zoom will be calculated.\n\n```javascript\nconst bbox = [\n  11.414795,51.835778,  // lng,lat of first point\n  11.645164,51.733833   // lng,lat of second point, ...\n];\n\nawait map.render(bbox);\nawait map.image.save('bbox.png');\n\n```\n#### Output\n![Map with bbox](https://stephangeorg.github.io/staticmaps/sample/bbox.png)\n\n***\n\n### Map with single marker\n\n```javascript\nconst marker = {\n  img: `${__dirname}/marker.png`, // can also be a URL,\n  offsetX: 24,\n  offsetY: 48,\n  width: 48,\n  height: 48,\n  coord: [13.437524, 52.4945528],\n };\nmap.addMarker(marker);\nawait map.render();\nawait map.image.save('single-marker.png');\n\n```\nYou're free to specify a center as well, otherwise the marker will be centered.\n\n#### Output\n![Map with marker](https://stephangeorg.github.io/staticmaps/sample/marker.png)\n\n***\n\n### Map with multiple marker\n```javascript\nconst marker = {\n  img: `${__dirname}/marker.png`, // can also be a URL\n  offsetX: 24,\n  offsetY: 48,\n  width: 48,\n  height: 48\n};\n\nmarker.coord = [13.437524,52.4945528];\nmap.addMarker(marker);\nmarker.coord = [13.430524,52.4995528];\nmap.addMarker(marker);\nmarker.coord = [13.410524,52.5195528];\nmap.addMarker(marker);\n\nawait map.render();\nawait map.image.save('multiple-marker.png');\n\n```\n#### Output\n![Map with multiple markers](https://stephangeorg.github.io/staticmaps/sample/multiple-marker.png?raw=true)\n\n***\n\n### Map with polyline\n```javascript\n\nvar line = {\n  coords: [\n    [13.399259,52.482659],\n    [13.387849,52.477144],\n    [13.40538,52.510632]\n  ],\n  color: '#0000FFBB',\n  width: 3\n};\n\nmap.addLine(line);\nawait map.render();\nawait map.image.save('test/out/polyline.png');\n\n```\n#### Output\n![Map with polyline](https://stephangeorg.github.io/staticmaps/sample/polyline.png?raw=true=800x280)\n\n***\n\n### Map with circle\n```javascript\n\n const circle = {\n  coord: [13.01, 51.98],\n  radius: 500,\n  fill: '#000000',\n  width: 0,\n};\n\nmap.addCircle(circle);\nawait map.render();\nawait map.image.save('test/out/099-circle.png');\n\n```\n#### Output\n![Map with circle](https://user-images.githubusercontent.com/7861660/129888175-c2209cca-6ede-43d7-bb8d-181fdd4cfa17.png)\n\n***\n\n### Blue Marble by NASA with text\n```javascript\nconst options = {\n    width: 1200,\n    height: 800,\n    tileUrl: 'https://map1.vis.earthdata.nasa.gov/wmts-webmerc/BlueMarble_NextGeneration/default/GoogleMapsCompatible_Level8/{z}/{y}/{x}.jpg',\n    zoomRange: {\n      max: 8, // NASA server does not support level 9 or higher\n    }\n  };\n\n  const map = new StaticMaps(options);\n  const text = {\n    coord: [13.437524, 52.4945528],\n    text: 'My Text',\n    size: 50,\n    width: '1px',\n    fill: '#000000',\n    color: '#ffffff',\n    font: 'Calibri'\n  };\n\n  map.addText(text);\n\n  await map.render([13.437524, 52.4945528]);\n  await map.image.save('test/out/bluemarbletext.png');\n```\n\n#### Output\n![NASA Blue Marble with text](https://i.imgur.com/Jb6hsju.jpg)\n\n***\n\n### Tile server with subdomains\n{s} - subdomain (subdomain), is necessary in order not to fall into the limit for requests to the same domain. Some servers can block your IP if you get tiles from one of subdomains of tile server.\n```javascript\nconst options = {\n    width: 1024,\n    height: 1024,\n    tileUrl: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',\n    tileSubdomains: ['a', 'b', 'c'],\n};\n\nconst map = new StaticMaps(options);\n\nawait map.render([13.437524, 52.4945528], 13);\nawait map.image.save('test/out/subdomains.png');\n```\n\n### Mulitple tile layers\n\n\n```javascript\nconst options = {\n    width: 1024,\n    height: 600,\n    tileLayers: [{\n      tileUrl: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',\n    }, {\n      tileUrl: 'http://www.openfiremap.de/hytiles/{z}/{x}/{y}.png',\n    }],\n};\n\nconst map = new StaticMaps(options);\n\nawait map.render([13.437524, 52.4945528], 13);\nawait map.image.save('test/out/multipleLayers.png');\n```\n\n#### Output\n![11-layers](https://user-images.githubusercontent.com/7861660/213999766-a6c7d2bc-5c90-4da4-9df7-08bcb08442ce.png)\n\n\n# Contributers\n\n+ [Stefan Warnat](https://github.com/swarnat)\n+ [Jordi Casadevall Franco](https://github.com/JOGUI22)\n+ [Joe Beuckman](https://github.com/jbeuckm)\n+ [Ergashev Adizbek](https://github.com/Adizbek)\n+ [Olivier Kamers](https://github.com/OlivierKamers)\n+ [Wesley Flynn](https://github.com/wesflynn)\n+ [Thomas Konings](https://github.com/tkon99)\n+ [Gihan S](https://github.com/gihanshp)\n+ [Sergey Averyanov](https://github.com/saveryanov)\n+ [boxcc](https://github.com/boxcc)\n+ [Maksim Skutin](https://github.com/mskutin)\n+ [Jorgen Phillips](https://github.com/JorgenPhi)\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FStephanGeorg%2Fstaticmaps","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FStephanGeorg%2Fstaticmaps","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FStephanGeorg%2Fstaticmaps/lists"}