Make buildings with heights in Elk for Grasshopper

I have recently been constructing whole cities in Rhino using the Elk plugin. This parses OpenStreetMap data into Grasshopper geometry, allowing you to visualise any city or area in the world in your Rhino viewport.

York in Grasshopper with Elk OpenStreetMap data

One of the most interesting ways of getting your cities to look like cities is getting the buildings right. It is possible to extract building data with Elk, but this isn’t intuitive if you aren’t already familiar with OpenStreetMap data. And even if you are, the output is a collection of points, which requires further work to turn it into actual buildings.

This article will show you how I created buildings by extracting the OSM data and converting them into 3D meshes.

OpenStreetMap: Understanding the data

A crash course into OpenStreetMap data: All (well, nearly all) objects in the map are either saved as points or as lists of points. Points are useful for small objects, such as benches, letterboxes or trees. For larger objects, such as roads and buildings, collections of points are used. For roads, these points join together to form lines along the centre of the road. For buildings, these points define the line around the building’s edge. These ‘point collections’ are essentially polylines.

Every object, whether a point or a polyline, has a list of data associated with it. Each item in this list has a key and a value. It is with these keys and values that we describe the object. The most common key is ‘name’, and we describe the name in the value field. Most objects have many tags. For example, if we go into the OpenStreetMap editor and have a look at a local branch of Costa Coffee:

OpenStreetMap tags values keys example

We have a list of keys and a list of values. The values are the data itself; the keys describe the type of data.

If you want to see this for yourself, go into the editor on OpenStreetMap. I personally prefer the Potlatch2 editor, which you can find in the drop-down next to the ‘edit’ button at the top. To see the tags, select an object on the map, then click ‘advanced’ in the bottom left.

Buildings in OpenStreetMap

Similarly, all buildings contain a collection of tags. The great thing about tags is that they are an open concept – you can use any tags that you like. With buildings, the most common tags include the building name and the building type. For example:

OpenStreetMap tags values keys example building

Using Elk to extract buildings

Elk can be used to extract the points that form the building outline. Like polylines in Rhino, the data is saved as a collection of points, and not a line itself, so it will be up to us to stitch the points together to create a building outline.

There is no built-in component that returns directly the building points, but we can use the GenericOSM to filter for data containing the ‘building’ key. The Polyline component joins the points together.

Grasshopper components Elk extract buildings

building outlines openstreetmap elk grasshopper

Make your buildings 3D

This is all well and good, but don’t they look a bit flat and boring? Let’s make them look a bit more realistic.

The easiest way to turn your polylines into 3D buildings is to extrude them, and then use patch to create a roof. But I can tell you through my own experience that this is a bad idea. For a few buildings it’s okay, but for the city scale, working with surfaces is very slow and you’ll quickly see your computer grind to a halt. To build our buildings at lightning speed, we have to use meshes.

There isn’t anything natively in Grasshopper that does this for us, but we can quickly write something in C#. Basically, we build up the walls with mesh faces, then use a Rhino command to cap the top for the roof.

This script takes in a list of points that describe the building outline, and a value for its height. (Let’s just send it a value of 10m or so for now.)

  private void RunScript(List<Point3d> pts, double ht, ref object A)
  {

    var building = new Mesh();

    //make walls
    for (int p = 0; p < pts.Count; p++)
    {
      building.Vertices.Add(pts[p]);
      building.Vertices.Add(new Point3d(pts[p].X, pts[p].Y, pts[p].Z + ht));
    }

    for (int p = 0; p < pts.Count - 1; p++)
    {
      int j = p * 2;
      building.Faces.AddFace(j, j + 1, j + 3, j + 2);
    }

    //make roof
    var roofpts = new List<Point3d>();
    for (int p = 0; p < pts.Count; p++)
    {
      roofpts.Add(building.Vertices[p * 2 + 1]);
    }
    var pline = new Polyline(roofpts);
    var roof = Mesh.CreateFromClosedPolyline(pline);
    building.Append(roof);

    A = building;

  }

This then gives us:

Elk Grasshopper example buildings

Elk Grasshopper example buildings

But not all buildings are 10 metres tall…

It made things a lot easier to assume a height for our buildings. But can we do any better?

Given that we have a height input, we should be able to put something a bit more sensible into it. Some buildings in OSM do come with height data, though most don’t. If they do, this information is under the height key. How can we extract the building’s height information and apply it to our buildings with Elk?

It currently isn’t easy as there isn’t a comprehensive tag filter within Elk. One solution is to use the GenericOSM with k=height. This will return everything with height data; we just have to assume that everything returned is a building (it usually is) and model it as such.

Set up your Grasshopper as below, using the same C# script as above to create the buildings:

Elk Grasshopper example buildings

For my example of York, barely a single building has any height data. But, very happily, one very patient mapper has recorded the height of all the different elements of York Minster, leading to a very pleasing model.

But I really want heights on ALL my buildings!

Then you’ll likely have to pay up.

At least in the UK, the only near-comprehensive source of building heights is via the Ordnance Survey Topography Layer. Limited amounts of data are available as free academic licences, but otherwise it ain’t cheap.

In the meantime, if you’ve made it this far, you’ve probably realised that there are a lot of gaps in the OSM database. These gaps are best filled by people with local knowledge where you live, so I would encourage you to register and to start mapping! 🙂

Modelling the city of York with Grasshopper, Elk and OpenStreetMap

Since my post last year on modelling cities in Grasshopper, I have learnt a few more things in how to get the most out of Grasshopper. I am now much more adept in using meshes, a much lighter data type than surfaces, and I have learnt a few more tricks in getting the buildings to look a little more building-like.

The combination of these means that I can now load in much larger areas into Grasshopper with much better performance. I decided to revisit the challenge of opening cities in Grasshopper and see where I could take it.

The city of York

In this post, I have modelled my historic home city of York. It is famous for its Minster and for its City Walls, and also has two rivers, numerous parks, and other historical buildings, which should make for some interesting renders.

Here is an actual photo of York:

Bird's eye view of York city centre

Image Wikipedia

And here is a rather awesome video of York:

Modelling in Grasshopper

As in my previous attempts, I am using OpenStreetMap map data. I download a map on the OSM export page, which provides an OSM file. I then use the Elk plugin for Grasshopper.

I have set up a standard Grasshopper file where I can connect it to any OSM file, and with no user intervention, it will generate a 3D model of the map data in this OSM file. The Grasshopper file is available here.

Results

Here is the above photo modelled in Grasshopper:

York in Grasshopper with Elk OpenStreetMap data

The buildings are mostly modelled using their outlines, which are available for most city centre locations and key landmarks. A very few buildings also have building height data, which allows the Minster to be modelled well. All buildings without height data are instead modelled by a random height of between 5 and 15 metres. (This gives a slightly more realistic appearance than, say, having all buildings to be 10m tall.)

York Minster

York Minster is a highly impressive structure, towering over the rest of the city.

_73551782_minster_wide

minster

Somebody has spent a lot of time and effort not only entering the height and outline of the Minster into the OSM database, but recording the heights and outlines of all the individual elements of the building. This means that we get a surprisingly intricate model of the Minster out of the box with no user intervention.

York in Grasshopper with Elk OpenStreetMap data - Minster

Foss Islands Road

Foss islands is an old industrial area near the city centre which is now mostly devoted to retail. A key landmark remains – an ominous Victorian chimney which stands slightly out of place next to a Morrisons supermarket.

Foss Islands York Morrisons and chimney

Image source

This also has height data, which produces some interesting views in its location next to the River Foss:

York in Grasshopper with Elk OpenStreetMap data - Foss Islands Road

Looking the other way, we can see the Minster in the distance:

York in Grasshopper with Elk OpenStreetMap data

York city walls

The city walls, around 800 years old, almost entirely circumnavigate the city centre.

York city walls, overlooking Minster

Image by Steve Nova: source

Unfortunately there is no automatic way to model the grass banks around the walls, but the walls are saved as polylines in OSM. These walls are made by converting the polylines into 2D meshes (the same as how the roads are generated) and then extruded 10m up. They are quite jagged though and could do with some more work.

York in Grasshopper with Elk OpenStreetMap data - walls and Minster

C# code and links

Some key code snippets used:

Roads

OSM roads are effectively polylines. In order to render them with colours, they need ‘expanding’ into 2D shapes that have a width. This is done by creating a mesh face for every polyline segment. The component for this is available here.

Buildings

Here is a more in-depth discussion on how to create buildings in 3D using OpenStreetMap data.

Grasshopper file

The whole Grasshopper file is available here.

Convert a network of roads into 2D curve plans in Grasshopper

Building on from my Road Maker, where the centrelines of roads can be converted into 2D meshes suitable for rendering more realistic roads in Grasshopper (as done here), a recent task at the office required that these meshes then be turned into a collection of curves marking the outline of the road.

This Grasshopper script enables you to do this, using a couple of standard Grasshopper components. The basic workflow used here is to get a network of roads using Elk and OSM data.

elk-1

The Road Maker then converts this network into 2D meshes. We then extract the mesh edges and then use the RUnion to tidy it up as much as possible. The final result isn’t perfect but should minimise the amount of manual work needed at the end.

elk-2

We should then get a result that looks like:

road-network-curves-grasshopper

Rendering cities in Rhino with OpenStreetMap data

This slideshow requires JavaScript.

Using the freely available map data from OpenStreetMap (OSM), it is possible to create maps and renders of towns and cities within Rhino.

Most of the hard work was done by the creators of Elk, a plugin for Grasshopper that parses OSM data files and returns geometry sorted into roads, rivers, railway lines and so on. It’s then just a matter of taking that geometry and modifying it to suit your visual requirements.

And once the data’s in Grasshopper, we can do all the usual crazy Grasshoppery stuff to it. In the last image above, I connected the buildings up to a bit of C# to show its distance to a given point using colour. I think I like this version of Bath more…

2015/03/31 Update: How to do this yourself

Great news! After some digging around I have stumbled upon the Grasshopper definition I used to create this. If you want to do this for your own town, it is quite simple:

  1. Visit OpenStreetMap. Zoom into the area of interest, click ‘Export’ at the top, and then the blue ‘Export’ button on the left. The file size should be much less than 10MB for decent performance. If the file is too big then zoom in and try again.
  2. Download Elk – which provides the Grasshopper components to parse the OSM file
  3. Download my Grasshopper definition and open it in Grasshopper. At the very left, import the OSM file.

This definition was made many months ago when my knowledge of meshes (and how to make them faster) was much less. I’ve since become more proficient in making really lightweight meshes. I think that Grasshopper can handle much larger maps than this current definition will allow, and one day I plan to see how far I can take it. But this will have to do for now 🙂

2015/07/11 Update 2

As promised, I have had another go at this, and I have now modelled the entire centre of my city York. Take a look and download the GH file here.