How to import 3D buildings from OpenStreetMap to Blender As an OpenStreetMap (OSM) user, but pretty newbie regarding to Blender (I know the basics, but never used in depth because I get lost) or developing, I would like to 3D print some buildings stored in OSM and maybe make some basic renderings/modifications with Blender. After having done some research I've come to two different workflows but unfortunately none of them work for me, so hopefully anyone can tell me how to improve them or provide another one:

Preamble: download OSM data

I have exported an OSM area into OSM's native format *.osm file (which is an xml file) from their website. Full explanations on exporting an OSM file can be found here. For purposes of this exercise I will be downloading this particular area, which looks like this on this 3D Viewer thanks to the work of the community.



The osm file that I am working with can be downloaded here as well.

Scenario 1: Using BlenderGis Addon

BlenderGis Addon provides a lot of interesting features for GIS users. Amongst others it can import osm files geolocate, terrain analysis... it seems great!

Unfortunately the osm importer only imports 2D information of the geometry, and no other osm information is stored (at least I haven't been able to find it).

I would still need to extrude each object and model their roofs, and I haven't found any fast way to do that. I have just created a feature request on their repo, but despite it seems quite active I do not know if it will be accepted.

Scenario 2: Using Blender Geo Addon

Due to those problems I tried Blender Geo Addon which can import buildings in 3D, judging by this awesome video. It seems it has everything I need, except for these annoying issues (for me):


Only buildings that make use of osm's key building:height are extruded. Unfortunately this key is less used than building:levels which is more approximate but easier to get.
All roofs are flat, something which is not always true in most areas. OSM has some keys in order to store information regarding roofs, such as their type (roof:type) orientation (roof:orientation) and so on. (more details on that on this wiki)
There seem to be many overlapping meshes. (less cleaner than the other solution)


This is the result of the import:



The good news is that all this OSM information is stored as custom properties. The bad news is that I do not know how to work with them.

Regarding issue 1. I was wondering if there could be a way to extrude each object by its building:levels custom property without having to review and extrude them one by one. 

Regarding issue 2: I do not have any idea on how to solve that. This is really a problem.

Regarding issue 3: I do not know if that's really a problem.

Final steps
In case I could fix the import problem my idea is to use 3D print toolbox and export the model into stl file.

Can anyone provide any clues to overcome these problems?
Here are some updates to the script https://github.com/vvoovv/blender-geo/blob/master/io_import_scene_osm.py

Extruded buildings based on building:levels using a level_height setting in import. Also added a scale setting.

https://gist.github.com/batFINGER/87ad90900be589281eeeaa83697d541f

Result So far.



Haven't done much with roofs yet.

Till I add it into code proper this adds some materials / object color to buildings

import bpy
from bpy import context

# CoDEmanX from BA.org
def hex_to_rgb(color_str):
    # supports '123456', '#123456' and '0x123456'
    (r,g,b), a = map(lambda component: component / 255, bytes.fromhex(color_str[-6:])), 1.0
    return (r,g,b,a)

scene = context.scene
# buildings with material

bm = [b for b in scene.objects if "building:colour" in b.keys()]
materials = {}
for b in bm:
    matname = b.get("building:material")
    if matname is None:
        matname = "building:material"
    mat = bpy.data.materials.get(matname)
    if mat is None:
        mat = bpy.data.materials.new(matname)
    mat.use_object_color = True
    if matname not in b.data.materials:
        b.data.materials.append(mat)
    if b.get("building:colour"):
        b.color = hex_to_rgb(b.get("building:colour"))


Might also pay to have a look at osm2x3d to convert to x3d and import from that format.  (Haven't tried)