# Map Machine: an OpenStreetMap renderer that tries to show every tag

> Map Machine is a Python renderer for OpenStreetMap that pairs the Röntgen icon set with a configurable style, so it can draw map features that standard renderers leave out, including tags with a single use. It produces static SVG maps, PNG tiles for slippy maps, and can run a tile server.

**enzet/map-machine** — Python renderer for OpenStreetMap with custom icons intended to display as many map features as possible

- Repository: https://github.com/enzet/map-machine
- Stars: 571 · Forks: 40
- Language: Python
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/enzet-map-machine

## Two commands, one of which talks to two APIs

Map Machine is a Python OpenStreetMap renderer that can easily create static SVG maps out of OpenStreetMap data, and it can also generate PNG tiles for slippy maps and run a tile server for them.

The first command renders a bounding box to an SVG file:

```shell
map-machine render -b 2.284,48.860,2.290,48.865
```

That will download OSM data through the OSM API and the Overpass API and render an SVG map of the specified area to out/map.svg.

The second command produces PNG tiles instead:

```shell
map-machine tile -b 2.361,48.871,2.368,48.875
```

which downloads OSM data and renders PNG tiles covering the specified area into the out/tiles directory.

The fact that data comes from two sources is worth pausing on, because it shapes what you can ask for. The OSM API is the place for bounded requests and for the raw geometry, and Overpass is a query engine over the database, which is how you get at tags that no ordinary renderer would ever request. A renderer that wants to show every feature in the data needs the second kind of access, and that is why an Overpass query language shows up in a project that also renders SVG.

The bounds are given as a comma separated set of coordinates, and the examples use Paris and Moscow locations. The output path convention is simple, a file called map.svg in the out directory for the render command and a tiles directory for the tile command, which makes the tool easy to script.

## The icon set is a separate project with a separate licence

The central feature of the project is the Röntgen icon set, and the readme is careful to separate the licences because they differ.

Röntgen is a set of monochrome 14 by 14 pixel icons specially created for the Map Machine project. Unlike the Map Machine source code, which is under the MIT licence, all icons are under the CC BY licence, and with the appropriate credit the icon set can be used outside the project.

That is a genuinely useful arrangement for a rendering project. The code is permissively licensed, the artwork is available under an attribution licence, and the attribution requirement is a single line rather than a blocker.

The icon package is a real dependency rather than a vendored folder. The dependency list includes roentgen-icons at roughly 0.15.0, which means the icon set is distributed as its own Python package and can be updated independently of the renderer.

The pixel dimensions are a design decision rather than an incidental detail. At 14 by 14 pixels, an icon is small enough to sit on a map without covering the geometry it describes, and the monospace alignment makes icons land on predictable pixel boundaries rather than half pixels, which is what keeps a dense map legible.

The stated idea behind the combination is worth repeating because it explains every other choice in the project: the aim is to have the possibility to show all the richness of the OpenStreetMap data, to display any map feature represented by OpenStreetMap data tags by means of colors, shapes and icons. For contributors that means displaying all changes even if they are small, and for map users it means digging down into the map and finding every detail that was mapped.

## This is a playground, and the readme says so

The positioning statement is unusual enough to be worth quoting at length, because it sets expectations that a normal renderer does not.

Unlike standard OpenStreetMap renderers, Map Machine is a playground for experiments where one can easily try to support any unsupported tag, proposed tagging scheme, tags with little or even single usage, deprecated ones that are still in use.

The consequence is stated right after. Map Machine is intended to be highly configurable, so it can generate precise but messy maps for OSM contributors as well as pretty and clean maps for OSM users. It can also use some slow algorithms for experimental features.

That is an honest description of a deliberate trade. A renderer that shows everything will by definition be busier than one that shows the important things, and the speed cost of checking every tag against every possible rendering is why slow algorithms are acceptable here. The project is not competing with Mapnik on the default map of a city; it is competing with the ability of a contributor to check their own work.

Several features follow directly from that goal. Map Machine can use more than one icon to visualise an entity, and it can use colours to visualise the colour tag value or other entity properties such as the genus or the substance type. Buildings can be drawn with isometric shapes and shaded in proportion to building:levels, building:min_level, height and min_height, under the --buildings isometric or --buildings isometric-no-parts options, which are not set by default. Road width comes from the width tag or is estimated from the lanes value, and lane separators are drawn when a lane value is given.

Tree rendering is a good example of the same idea, since Map Machine can visualise trunk diameter, circumference and diameter_crown, leaf types as broadleaved or needle-leaved, leaf cycles as deciduous or evergreen, and genus or taxon such as birch, palm and maple.

There are also location specific details, like the Japanese map symbols called chizukigou that are enabled with the --country jp option, and the direction sectors for viewpoints and surveillance, with a 15 degree angle when none is given, a radial gradient for surveillance and an inverted one for viewpoints.

## Colours, power infrastructure and a deliberate dependency set

The styling rules are where the tag coverage becomes visible, and two examples show the range.

Map icons take the colour tag value if it is present, and otherwise icons are displayed in dark grey by default, purple for shop nodes, red for emergency features, with special colours for natural features. The renderer also takes building:colour, roof:colour and other asterisk-colour tags into account, and uses the colour tag value to paint subway lines.

Power infrastructure gets the same treatment, with the design tag values used with power equals tower and power equals pole rendered in many variants, which is a category of map detail that most general renderers reduce to a single icon or omit.

The dependency list explains the technical approach. Shapely handles the geometry, numpy the array work, CairoSVG is what turns the generated SVG into raster output, Pillow handles images, svgwrite produces the SVG itself, colour resolves colour names, PyYAML the configuration, gpxpy the GPS track handling, portolan is the tile maths, and urllib3 the network access. There is a typing_extensions dependency and the package is marked as typed.

The package requires Python 3.10 or newer, is classified as a beta development status, and its keywords cover cartography and geospatial work alongside the map terms. The command is a single console script, map-machine, pointing at map_machine.main:main, and the version is dynamic, so it comes from the source tree rather than being written into the manifest.

The container image is a python:3.10-slim-bullseye base with the cairo and geos development packages installed, since CairoSVG and Shapely need them, a /maps directory created and exposed as a volume, and the map-machine command as the entry point. The volume is the cache, so a container that is thrown away without it loses its downloaded data.

## A small project with a real release and a broad test layout

The maintenance facts are modest, and the repository layout is conventional for a Python project with a lot of fixture data.

The repository is not archived, the default branch is main, and the last push was on 2026-05-26, about five months before the current date. There is one release, v0.3.0 from 2026-02-07, and the project is classified as a beta. The licence is MIT with a LICENSE file at the root, and the author is Sergey Vartanov.

The top level is map_machine/ for the package, data/ for the icon and configuration data, doc/ for the documentation and the example images referenced in the readme, tests/ for the suite, plus a Dockerfile, a CHANGELOG.md, a CONTRIBUTING.md and a .devcontainer/ directory. The githooks directory and the .githooks/ configuration suggest the commit hooks are managed in the repository rather than left to each contributor.

The dependency list is short enough to read as a design statement. CairoSVG for the SVG to raster path, colour for resolving colour names, gpxpy for track files, numpy, Pillow, portolan for the tile maths, PyYAML for configuration, roentgen-icons for the icon set, Shapely for geometry, svgwrite for emitting the SVG, and urllib3 for HTTP. There is no framework dependency, no web server library and no ORM, which is consistent with a tool that runs as a command, renders into a directory and exits.

The development extra is equally small, with pytest, ruff and a type checker, and the package is built with setuptools and a wheel, with package data included and the package finder scoped to map_machine subpackages.

The one thing to plan for is the data volume. The tool downloads OpenStreetMap data through the Overpass API, and Overpass has usage limits, so the practical workflow for anyone testing this is to work on small bounding boxes first, which is what all the examples in the readme do.

## Conclusion

Map Machine suits an OpenStreetMap contributor who wants to see what the data actually contains, including the rare and the deprecated tags, and a cartography experimenter who wants a style that can be pushed into unusual territory. It does not suit someone who wants a clean everyday map, since the project describes its own output as precise but messy as an option, and it does not suit a production tile service without reading the caching and server behaviour. Before running it, install the roentgen-icons package for the icon set, keep the config directory persistent, and expect the default SVG output rather than a rendered image, since the SVG is the primary artefact.

## FAQ

### What is Map Machine?

It is a Python OpenStreetMap renderer that can easily create static SVG maps out of OpenStreetMap data, and can also generate PNG tiles for slippy maps and run a tile server for them. It uses the Röntgen icon set to display map features.

### How do I render a map with Map Machine?

Run map-machine render with a bounding box such as map-machine render -b 2.284,48.860,2.290,48.865, which downloads OSM data through the OSM API and Overpass API and renders an SVG map of that area to out/map.svg. The tile subcommand does the same but writes PNG tiles to the out/tiles directory.

### What licence applies to the Map Machine icons and code?

The Map Machine source code is under the MIT licence, while all the Röntgen icons are under the Creative Commons Attribution licence. With the appropriate credit the icon set can be used outside the project, and the icons ship as the separate roentgen-icons package.

### What can Map Machine draw that other renderers do not?

It is intended as a playground for experiments where one can try to support any unsupported tag, a proposed tagging scheme, tags with little or single usage, and deprecated ones still in use. It can use more than one icon per entity, colour by the colour, the genus or the substance tags, draw isometric buildings, lane separators, tree species and leaf cycles, and the Japanese chizukigou map symbols with the --country jp option.

## Sources

- [enzet/map-machine on GitHub](https://github.com/enzet/map-machine)
- [Issues](https://github.com/enzet/map-machine/issues)
- [License: MIT](https://github.com/enzet/map-machine/blob/main/LICENSE)
- [README](https://github.com/enzet/map-machine/blob/main/README.md)
- [Releases](https://github.com/enzet/map-machine/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/enzet-map-machine
