The third in a three-part series on the technical architecture of the iD editor. Previously we looked at iD’s core data types and actions and modes, behaviors, and operations.

Let’s look at how iD renders entities on the map and its pattern for abstracting other UI components.

Map Rendering

The core of iD’s map rendering system is iD.Map, which takes care of the map projection, zooming and panning, and states like center and zoom level. iD.Map also coordinates a system of smaller pieces that render a vector map.

For rendering entities on screen, iD adopts a geometric vocabulary that’s a higher-level representation than OSM’s simple data model:

  • A point is a node that is not a member of any way.
  • A vertex is a node that is a member of at least one way.
  • A line is a way that is not an area.
  • An area is a way that is circular and has certain tags, or a series of one or more ways grouped in a multipolygon relation.


For each of these geometric types, iD.svg has a corresponding module: iD.svg.Points, iD.svg.Vertices, iD.svg.Lines, and iD.svg.Areas. iD.Map delegates to these modules to render entities on screen.

Each piece of data is connected to the rendering with d3’s join system. When iD loads and renders an entity for the first time, it is part of the enter selection and the SVG elements needed to represent it are created. When a user modifies an entity, it is part of the update selection and the appropriate attributes of the SVG element, like those that specify the location on screen, are updated. And when a user deletes an entity or moves it offscreen, the corresponding SVG element is in the exit selection, and will be removed.

The iD.svg modules apply classes to SVG elements based on tags, via iD.svg.TagClasses. For example, an entity tagged with highway=residential gets two classes: .tag-highway and .tag-highway-residential. This allows distinct visual styles to be applied via CSS at either the key or key-value levels. Elements also receive a class corresponding to their entity type (node, way, or relation) and one corresponding to their geometry type (point, line, or area).

The iD.svg namespace has a few other modules that don’t have a one-to-one correspondence with entities:

  • iD.svg.Midpoints renders small “virtual nodes” at the midpoints between two vertices.
  • iD.svg.Labels renders textual labels.
  • iD.svg.Surface sets up a stack of SVG groups that ensure that map elements appear in an appropriate z-order.

Other UI

iD provides many user interface elements beyond than the map, including the page footer, an interface for saving changes, and geocoding controls.

Geocoder UI

The implementations for all non-map UI components live in the iD.ui namespace. These modules follow a pattern for reusable d3 components Mike Bostock suggested in the context of charts. The entry point to a UI element is a constructor function; for example iD.ui.Geocoder(). The constructor function may require a set of mandatory arguments. Most UI components require exactly one argument: a context object produced by the top-level iD() function.

A component needs some way to be rendered on screen by creating new DOM elements or manipulating existing elements. This is done by calling the component as a function, and passing a d3 selection where the component should render itself:

var container ='body').append('div')
    .attr('class', 'map-control geocode-control');

var geocoder = iD.ui.Geocoder(context)(container);

Alternatively, and more commonly, the same result is accomplished with d3.selection#call:'body').append('div')
    .attr('class', 'map-control geocode-control')

Some components are reconfigurable and provide functionality beyond basic rendering, by providing methods off of the function:

var inspector = iD.ui.Inspector();
inspector(container); // render the inspector
inspector.tags(); // retrieve the current tags
inspector.on('change', callback); // get notified when a tag change is made

Future Direction

We hope you enjoyed the deep dive on iD’s technical internals. As iD evolves, no doubt some of these details will change, and new architectural pieces will emerge as we build out remaining features like presets. We’ve captured the text of these posts in the file in the iD repository, and will keep it up to date as the project matures.

Devlogging work on the OpenStreetMap project by the MapBox team.

Much of this work is currently focused on improvements to OpenStreetMap funded by the Knight Foundation

Follow our work here on this blog or subscribe to our Twitter feed. You can subscribe to this blog’s feed or follow us at