{"id":22419463,"url":"https://github.com/dunkelstern/osmtile","last_synced_at":"2026-04-29T13:34:48.804Z","repository":{"id":142590510,"uuid":"134329147","full_name":"dunkelstern/osmtile","owner":"dunkelstern","description":"OpenStreetMap map renderer in python (via cairo)","archived":false,"fork":false,"pushed_at":"2018-05-31T01:09:57.000Z","size":3084,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-08T22:33:58.326Z","etag":null,"topics":["cairo","map","openstreetmap","python3","renderer","shapely"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dunkelstern.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"publiccode":null,"codemeta":null}},"created_at":"2018-05-21T21:52:28.000Z","updated_at":"2018-05-31T01:09:59.000Z","dependencies_parsed_at":null,"dependency_job_id":"d1a91937-cfb9-4f82-8ed5-18f2e7ef950a","html_url":"https://github.com/dunkelstern/osmtile","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dunkelstern/osmtile","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunkelstern%2Fosmtile","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunkelstern%2Fosmtile/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunkelstern%2Fosmtile/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunkelstern%2Fosmtile/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dunkelstern","download_url":"https://codeload.github.com/dunkelstern/osmtile/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunkelstern%2Fosmtile/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32427715,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T13:34:34.882Z","status":"ssl_error","status_checked_at":"2026-04-29T13:34:29.830Z","response_time":110,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["cairo","map","openstreetmap","python3","renderer","shapely"],"created_at":"2024-12-05T16:15:51.040Z","updated_at":"2026-04-29T13:34:48.792Z","avatar_url":"https://github.com/dunkelstern.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OSMTile\n\nPython implementation for a OSM Map-Renderer\n\n![Example rendering](doc/series.gif)\n\n## TODO\n\n- Node rendering (Icons)\n- Effects (icon fill, pattern fill, etc.)\n\n## Quick and dirty how-to\n\n1. Create a PostgreSQL Database with PostGIS activated\n2. Fetch a copy of [imposm3](https://github.com/omniscale/imposm3)\n3. Get a OpenStreetMap data file (for example from [Geofabrik](http://download.geofabrik.de/), start with a small region!)\n4. Import some OpenStreetMap data into the DB:\n```bash\n$ imposm import -connection postgis://user:password@host:port/database -mapping doc/imposm_mapping.yml -read /path/to/osm.pbf -write -deployproduction\n```\n5. Create a virtualenv and install packages:\n```bash\nmkvirtualenv -p /usr/bin/python3 osmtile\npip install -r requirements.txt\n```\n6. Render a map:\n```bash\npython render.py --config config/config.json 48.3849 10.8631 14\n```\n\n## Layer config\n\n### Global\n\nGlobal configuration for the map\n\nExample:\n\n```json\n{\n    \"global\": {\n        \"background\": \"#f0f0f0\",\n        \"projection\": \"merc\",\n        \"min_zoom\": 0,\n        \"max_zoom\": 22,\n        \"area\": {\n            \"xmin\": -20037508.34,\n            \"ymin\": -20037508.34,\n            \"xmax\": 20037508.34,\n            \"ymax\": 20037508.34\n        },\n        \"database\": {\n            \"user\": \"osm\",\n            \"dbname\": \"osm\"\n        }\n    }\n}\n```\n\n- `minzoom` Minimal zoom level (usually 0, fit the world into viewport)\n- `maxzoom` Maximal zoom level (usually 22, displays full detail)\n- `projection` usually `merc` for spherical mercator\n- `area` Mapping area in projected coordinates\n    - `xmin`\n    - `ymin`\n    - `xmax`\n    - `ymax`\n- `database`\n    - `user`\n    - `password`\n    - `dbame`\n    - `hostname`\n    - `port`\n- `background` background color\n\n### Definitions\n\n#### Fonts\n\nExample:\n\n```json\n{\n    \"fonts\": {\n        \"country\": {\n            \"face\": \"DejaVu Sans\",\n            \"size\": 50,\n            \"style\": \"regular\",\n            \"weight\": 800,\n            \"halo_size\": 3\n        },\n        \"road\": {\n            \"face\": \"DejaVu Sans\",\n            \"size\": 14,\n            \"style\": \"regular\",\n            \"weight\": 400,\n            \"halo_size\": 1\n        }\n    }\n}\n```\n\n- Dict: key = short Name or string (filename) or array (list of filenames)\n- Value: Dict\n    - face\n    - size\n    - style (regular, italic)\n    - weight\n    - halo size\n\n#### Colors\n\nExample:\n\n```json\n{\n    \"colors\": {\n        \"road_residential\": [0.8, 0.8, 0.8, 1.0],\n        \"road_motorway\": [0.8, 0.8, 0.0, 1.0],\n        \"forest\": [0.3, 0.9, 0.3, 1.0],\n        \"moor\": [0.3, 0.3, 0.0, 1.0]\n    }\n}\n```\n\n- Dict: key = short Name or string (filename) or array (list of filenames)\n- Value one of:\n    - Array [r, g, b, a]\n    - HTML Hex color: `#rrggbbaa`, shorthands allowed: `#rgb`.\n      If alpha is skipped it is assumed as 1.0/fully opaque\n    - Function:\n        - `darken(\u003ccolor\u003e, \u003cpercentage\u003e)`\n        - `lighten(\u003ccolor\u003e, \u003cpercentage\u003e)`\n        - `saturation(\u003ccolor\u003e, \u003cpercentage\u003e)`\n        - `alpha(\u003ccolor\u003e, \u003cpercentage\u003e)`\n\n#### Icons\n\nExample:\n\n```json\n{\n    \"icons\": {\n        \"forest\": {\n            \"filename\": \"img/tree@2x.png\",\n            \"colorize\": \"darken(forest, 20%)\",\n            \"scale\": 0.5\n        },\n        \"moor\": {\n            \"derive\": \"forest\",\n            \"colorize\": \"moor\"\n        },\n        \"motorway\": {\n            \"filename\": \"img/motorway@2x.png\",\n            \"scale\": 0.5,\n            \"split_positions\": [5, 5]\n        }\n    }\n}\n```\n\n- Dict: key = short Name or string (filename) or array (list of filenames)\n- Value: Dict\n    - `filename` (load from file, png or svg)\n    - `derive` (derive from other icon)\n    - `colorize` (use only alpha of icon and apply color or function)\n    - `scale` (scale the image, used for @2x icons to facilitate retina rendering)\n    - `split_positions` array of two pixel positions where to split the icon to fit text if used as shield, second value is pixels from the right boundary\n\n#### Styles\n\nExample:\n\n```json\n{\n    \"styles\": {\n        \"road_residential\": {\n            \"fill_color\": \"road_residential\",\n            \"stroke_color\": \"darken(road_residential, 20%)\",\n            \"description_font\": \"road\",\n            \"text_color\": \"darken(road_residential, 20%)\",\n            \"halo_color\": [1.0, 1.0, 1.0, 1.0]\n        },\n        \"road_motorway\": {\n            \"fill_color\": \"road_motorway\",\n            \"stroke_color\": \"darken(road_motorway, 20%)\",\n            \"description_font\": \"road\",\n            \"text_color\": \"darken(road_motorway, 20%)\",\n            \"halo_color\": [1.0, 1.0, 1.0, 1.0],\n            \"shield_icon\": \"motorway\"\n        },\n        \"forest\": {\n            \"fill_color\": \"forest\",\n            \"font\": \"road\",\n            \"text_color\": \"darken(forest, 20%)\",\n            \"halo_color\": \"lighten(forest, 20%)\",\n            \"fill_pattern_icon\": \"forest\",\n            \"fill_pattern_spacing\": 30\n        }\n    }\n}\n```\n\nValue: Dict key = short name or string (filename) or array (list of filenames)\n\n- `fill_color` polygon or line stroke fill color\n- `stroke_color` polygon outline or stroke outline color\n- `description_font` font to use for text\n- `text_color`\n- `halo_color` Text outline halo color to use\n- `fill_pattern_icon` Fill the polygon with a sparse fill of this icon\n- `fill_pattern_spacing` Pixels between renditions of the pattern icons\n- `fill_style` one of `solid`, `diagonally_hatched`, `horizontally_hatched`, `vertically_hatched`, `stippled`, `roughly_stippled`, `dashed` or `none`, defaults to `solid`\n- `stroke_style` one of `solid`, `dashed`, `stippled`, `fanned`, `patterned`\n- `stroke_pattern_icon` icon to repeat on the stroke line if `patterned` has been selected\n- `stroke_pattern_spacing` spacing in pixels between renditions of the pattern icons\n- `shield_icon` render icon behind description text\n\n### Zoomlevels\n\n```json\n{\n    \"layers\": {\n        \"12\": [\n            {\n                \"name\": \"Forests\",\n                \"db_table\": \"areas\",\n                \"type\": \"polygon\",\n                \"style\": \"forest\",\n                \"filter\": {\n                    \"designation\": [\n                        { \"=\": \"forest\" }\n                    ]\n                }\n            },\n            {\n                \"name\": \"Roads\",\n                \"db_table\": \"roads\",\n                \"type\": \"line\",\n                \"text_column\": \"name\",\n                \"style\": \"road_residential\",\n                \"width\": 5,\n                \"stroke\": 1\n            },\n            {\n                \"name\": \"Motorways\",\n                \"db_table\": \"motorways\",\n                \"type\": \"line\",\n                \"text_column\": \"name\",\n                \"style\": \"road_motorway\",\n                \"width\": 9,\n                \"stroke\": 2\n            }\n        ]\n    }\n}\n```\n\n- You can skip layers that will have the same config as a previous one.\n- You have to define the first zoom level you want to support and the last one (even if the last is a duplicate)\n\nDict: key = level\nValue: array (see below) or string (filename)\n\n#### Layer definition\n\nIf array item is a string then it defines a file to load,\nif it is a dict the layer definition is inline\n\n- `name`\n- `db_table`\n- `type` one of\n    - `node` (renders icons),\n    - `polygon` (renders polygons),\n    - `line` (renders lines of constant width)\n- `text_column`\n- `style`\n\n##### Node type\n\n- `icon`\n\n##### Polygon type\n\n- `3d` make pseudo 3d shapes for buildings, bigger values are bigger effect\n- `stroke` stroke width in pixels\n\n##### Line type\n\n- `width` width in pixels\n- `stroke` stroke width in pixels\n\n##### Filter\n\nArray of Dicts\n\n- Key: db field\n- Value: Array of dict (or choices)\n    - Key: operator (`=`, `\u003c=`, `\u003e=`, `\u003c`, `\u003e`, `!=`)\n    - Value: operator value\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdunkelstern%2Fosmtile","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdunkelstern%2Fosmtile","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdunkelstern%2Fosmtile/lists"}