Skip to content

Roof attributes and shapes ​

RoofsLayer draws real 3D roofs (gabled, hipped, domes, …) on top of your own fill-extrusion buildings and shortens each building's walls by the roof it draws. It reads plain attributes from a vector (or GeoJSON) source. This page lists the attributes a tileset needs, how each value is read, and how every OpenStreetMap roof:shape value is drawn.

Tileset requirements ​

  • A vector or GeoJSON source with one feature per building outline and per building part (polygons or multipolygons).
  • Feature ids. Every feature needs an id (numeric ids, or promoteId on the source). The layer uses them to shorten walls through feature state.
  • Attribute names follow Overture's building schema by default. Other sources map their names with fields, e.g. fields: { roof_shape: 'roof:shape', roof_angle: 'roof:angle' }.
  • Your walls: a fill-extrusion layer on the same source, passed as extrusionLayer. Give it filter: ['!=', ['get', 'has_parts'], true], so outlines drawn by their parts don't hide those parts' roofs.

Only buildings with a recognised roof_shape (and a height) get a roof; every other building keeps its flat extrusion.

Attributes ​

AttributeRequiredTypeMeaningOSM tagOverture column
roof_shapeyesstringRoof shape, see Roof shapesroof:shaperoof_shape
heightyesnumber (m)Top of the building or part, including its roofheight (or building:levels, below)height (or num_floors, below)
min_heightno (0)number (m)Bottom of the part (for parts that start above ground)min_height / building:min_levelmin_height (or min_floor)
roof_heightnonumber (m)Height of the roof alone, eaves to toproof:height (or roof:levels)roof_height
roof_anglenonumber (°)Pitch of the roof faces; used only when there is no roof_heightroof:angle—
roof_directionnonumber (°) or N/ECompass bearing the main roof face looks towardroof:directionroof_direction
roof_orientationnoalong/acrossRidge along or across the longest side of the outlineroof:orientationroof_orientation
roof_colornoCSS colourRoof colourroof:colourroof_color
roof_materialnostringPicks a roof colour when no roof_color is setroof:materialroof_material
facade_colornoCSS colourWall colour (gable ends; the extrusion too with wallColors: true)building:colourfacade_color
facade_materialnostringPicks a wall colour when no facade_color is setbuilding:materialfacade_material
has_partsrecommendedbooleanThe outline is drawn by its building:parts: no roof of its ownderived (a part lies inside the outline)has_parts

How values are read:

  • Numbers may be numbers or numeric strings ("12"). Non-numeric values are ignored.
  • height must be greater than min_height, or the building gets no roof.
  • roof_height must be positive. It is capped at the part's full height span (a part that is all roof, like a spire, can be).
  • roof_angle must be between 0 and 90 (exclusive).
  • roof_direction takes degrees clockwise from north, or a 16-point compass value (N, NNE, … NNW). It snaps to the nearest wall within the precision it was written with, as OSM2World does: 45° for compass letters, 10° for whole degrees, 0.5° for decimals.
  • Numbers written with a decimal comma (3,5) are read as 3.5.
  • Without height, num_floors gives it (3 m a floor, plus roof_height when tagged), and min_floor gives min_height. Use buildingHeight() / buildingBase() for the walls so they match.
  • roof_orientation other than along / across is ignored.
  • has_parts accepts true, 1, "true" or "yes".
  • Shape names are matched case-insensitively, and _ / - are interchangeable (half-hipped, half_hipped and Half-Hipped are the same).

Roof height ​

The roof is drawn inside the building's height: walls are shortened by the roof height, so the top of the roof sits at height.

  1. roof_height if set, capped at height − min_height.
  2. Otherwise roof_angle, if set: tan(angle) × run, capped at height − min_height. The run is the horizontal distance one roof face covers:
    • gabled-family shapes, butterfly, crosspitched: half the width across the ridge;
    • skillion: the full width;
    • sawtooth: one tooth (the angle sets every tooth);
    • pyramidal, cone: the radius (half the shorter side).
    • Ignored for curved roofs (dome, onion, round), which have no single pitch.
  3. Otherwise a default height: tan(30°) × half the shorter side (half a tooth for sawtooth), or the radius for curved roofs. That is a 30° pitch for gabled-family roofs; a skillion, whose face spans the full width, comes out shallower. The default is capped at half of height − min_height, and a building whose default comes out under 0.5 m gets no roof.

Roof direction and the ridge ​

Roofs are laid out on the outline's tight bounding box, with the ridge along one axis:

  • With roof_direction, the main face looks toward that bearing and the ridge runs perpendicular to it. A skillion slopes down toward the bearing; sawtooth teeth slope down toward it, with their glazing facing away.
  • Otherwise the ridge runs along the longest side, or across it with roof_orientation=across.
  • hipped, half_hipped, hipped_and_gabled and mansard always put the ridge on the longer axis of the box, since their end slopes assume it.

Roof shapes ​

Drawn as their real shape ​

roof_shapeDrawn asIn Overture
gabledTwo slopes meeting at a central ridge; vertical gable endsyes
saltboxGable with the ridge off-centre (moved by a third of the half-width), so one slope is longeryes
hippedFour slopes; the ridge is shortened by the hips at each endyes
half_hippedGable ends up to half height, small hips above (jerkinhead)yes
side_hippedHipped at one end, gabled at the end where other parts are attached (both ends hipped if unknown)no
side_half_hippedThe same with a half hipno
hipped_and_gabledHips up to half height, small vertical gables above (Dutch gable)no
gambrelBarn roof: steep lower part on both long sides, shallower upper part; gable endsyes
mansardGambrel profile on all four sidesyes
skillionOne slope, high at the back, low toward roof_directionyes
roundHalf-cylinder vault along the ridge (8 facets)yes
bellcast_gableGable whose slopes flatten into a flare near the eavesno
butterflyV shape: eaves at full height on both long sides, valley along the middleno
crosspitchedTwo crossing gables: gable ends on all four sides, meeting at a central peakno
sawtoothRepeated single slopes (~8 m teeth, whole number across the building) with near-vertical glazingyes
pyramidalSlopes from every outline edge up to a central apexyes
coneSlopes from every outline point up to a central apex: a true cone on a round outline, and the whole footprint covered on any otherno
domeHemisphere-like dome on a circle inside the outline (corners of a square outline stay flat)yes
onionOnion dome (OSM Buildings profile)yes

Near-vertical faces (gable ends, the small gables of hipped_and_gabled, sawtooth glazing) take the wall colour; sloped faces take the roof colour.

Aliases (drawn as the nearest shape) ​

roof_shapeDrawn asNotes
sphericaldomeOverture's name for a dome
pyramidpyramidalSynonym
pitchedgabledSynonym
lean_to, monopitch, shedskillionSynonyms
gabled_height_moved, gabled_irregularsaltboxUneven gable; no OSM tag says where the ridge sits, so a fixed offset is used
double_saltbox, quadruple_saltboxmansardClose, not exact

No roof (the building keeps its flat extrusion) ​

roof_shapeWhy
flatAlready right: the extrusion's top is the roof
many, mixed, mix, multiDiscouraged in OSM; such buildings are normally drawn by their building:parts
gabled_rowUndefined in OSM
anything else, or missingUnknown values (including typos like 2 faces (pitched)) are ignored

Colours ​

  • roof_color / facade_color accept #rgb, #rrggbb, CSS colour names (red, darkslategray, …), and rgb() / hsl(). Named colours are parsed literally (red is #ff0000).

  • Materials pick a colour when no colour is set (palette from OSM Buildings):

    Material (aliases)Colour
    roof_tiles (tile, tiles, rooftiles)#f08060
    brick (bricks)#cc7755
    slate (slates)#666666
    tar_paper (asphalt, bitumen, tar, roofingfelt, shingle, shingles)#333333
    metal (steel)#aaaaaa
    copper#a0e0d0
    concrete, plaster (plastered)#999999
    stone (block, masonry, granite, sandstone, paving_stones)#996666
    glass (glas, glassfront)#e8f8f8
    wood#deb887
    plants (grass, thatch)#009933
    canvas (sheet, sheets, tent), panel (panels)#fff8f0
    bronze / silver / gold#ffeecc / #cccccc / #ffcc00
  • Defaults: roofs #b9a99a; walls and gable ends use the layer's gableColor (#d9d4ce).

  • Facade colours (tagged or from a material) are toned down to 60 % saturation and a 30–88 % lightness range, the same on gable ends and extruded walls. Untagged walls keep the style's colour.

  • Roof faces are toned down as OSM Buildings does: every roof colour (tagged, from a material, or the default) is drawn at 70 % of its HSL saturation, so red becomes a brick red. Each building's roof lightness also shifts by ±0.03 or ±0.06 (stable for its feature id), so rows of identical roofs stay distinguishable. Wall-coloured faces (gable ends, glazing) are left as tagged, so they keep matching the extrusion walls.

Getting roof data ​

Overture's official tiles ​

Each Overture release publishes worldwide building tiles (PMTiles, zooms 5–14) with exactly the attributes above and numeric feature ids, buildings and building parts in separate source layers (building, building_part): give RoofsLayer one wall layer per source layer (see Roof shapes). For your own hosting, cut a region with pmtiles extract:

sh
pmtiles extract https://overturemaps-extras-us-west-2.s3.amazonaws.com/tiles/2026-09-23.1/buildings.pmtiles \
  paris.pmtiles --bbox=2.25,48.81,2.42,48.91

Overture limits roof_shape to 14 values (dome, flat, gabled, gambrel, half_hipped, hipped, mansard, onion, pyramidal, round, saltbox, sawtooth, skillion, spherical), so OSM-only shapes such as side_hipped, butterfly, crosspitched or hipped-and-gabled arrive as one of these or not at all, and there is no roof_angle.

Your own source ​

Any source works if it carries the attributes above under these names, or under its own names mapped with fields. A source straight from OSM tags, for example:

ts
new RoofsLayer({
  id: 'roofs',
  source: 'osm-buildings',
  sourceLayer: 'building',
  extrusionLayer: 'osm-buildings-3d',
  fields: {
    roof_shape: 'roof:shape',
    roof_height: 'roof:height',
    roof_angle: 'roof:angle',
    roof_direction: 'roof:direction',
    roof_orientation: 'roof:orientation',
    roof_color: 'roof:colour',
    roof_material: 'roof:material',
    facade_color: 'building:colour',
    facade_material: 'building:material',
  },
});

height must still be in metres and include the roof, and has_parts must be computed (OSM has no such tag).

Sources ​

MIT licensed. Models: Open Landmarks; map data © OpenStreetMap contributors and Overture Maps Foundation.