Wiki ▸ [[API Reference]] ▸ [[Geo]] ▸ Geo Paths

For cartographic visualizations, D3 supports a handful of components for displaying and manipulating geographic data. These components use the GeoJSON format—a standard way of representing geographic features in JavaScript. (See also the TopoJSON format, an extension of GeoJSON that is significantly more compact.) To convert shapefiles to GeoJSON, use ogr2ogr, part of the GDAL package.

Some other tools you may be interested in:

  • TopoJSON - shapefile simplification, topology construction and GeoJSON compression.
  • Shapely - manipulation of planar geometry objects.
  • ColorBrewer - color scales for maps.
  • PostGIS - a geospatial database.

The primary mechanism for displaying geographic data is d3.geo.path. This class is similar to d3.svg.line and the other SVG shape generators: given a geometry or feature object, it generates the path data string suitable for the "d" attribute of an SVG path element. The d3.geo.path class can render directly to Canvas, which may offer better performance when animating the projection.

# d3.geo.path()

Creates a new geographic path generator with the default settings: the albersUsa projection and a point radius of 4.5 pixels.

# path(feature[, index])

Returns the path data string for the given feature, which may be any GeoJSON feature or geometry object:

  • Point - a single position.
  • MultiPoint - an array of positions.
  • LineString - an array of positions forming a continuous line.
  • MultiLineString - an array of arrays of positions forming several lines.
  • Polygon - an array of arrays of positions forming a polygon (possibly with holes).
  • MultiPolygon - a multidimensional array of positions forming multiple polygons.
  • GeometryCollection - an array of geometry objects.
  • Feature - a feature containing one of the above geometry objects.
  • FeatureCollection - an array of feature objects.

The type "Sphere" is also supported, which is useful for rendering the outline of the globe. A sphere has no coordinates. An optional index may be specified, which is passed along to the pointRadius accessor; the index is passed automatically when the path generator is invoked by selection.attr.

Important: the inside of a polygon is all points that the polygon winds around in a clockwise order. If your GeoJSON input has polygons in the wrong winding order, you must reverse them, say via ST_ForceRHR; you can also convert your GeoJSON to TopoJSON, and this will happen automatically.

To display multiple features, you can place them in a single feature collection and a single path element:

svg.append("path")
    .datum({type: "FeatureCollection", features: features})
    .attr("d", d3.geo.path());

Alternatively, you can create multiple distinct path elements:

svg.selectAll("path")
    .data(features)
  .enter().append("path")
    .attr("d", d3.geo.path());

Using distinct path elements is typically slower than a single path element for a collection. However, distinct path elements are preferred if you want interact with features separately (e.g., using CSS :hover or click events).

# path.projection([projection])

If projection is specified, sets the projection used by the path generator to the specified projection function. If projection is not specified, returns the current projection, which defaults to albersUsa. The projection is typically one of D3's built-in geographic projections; however, any function can be used. A projection function takes a two-element array of numbers representing the coordinates of a location, [longitude, latitude], and returns a similar two-element array of numbers representing the projected pixel position [x, y]. For example, a rudimentary spherical Mercator projection:

function mercator(coordinates) {
  return [
    coordinates[0] / 360,
    (-180 / Math.PI * Math.log(Math.tan(Math.PI / 4 + coordinates[1] * Math.PI / 360))) / 360
  ];
}

Internally, this point projection function is wrapped with a fallback stream transformation that performs adaptive resampling. However, the fallback stream does not perform any clipping or cutting.

For more control over the stream transformation, the projection may be specified as an object that implements the stream method. (See example.) The stream method takes an output stream as input, and returns a wrapped stream that projects the input geometry; in other words, it implements projection.stream.

If projection is null, the path uses the identity transformation, where the input geometry is not projected and is instead rendered directly in raw coordinates. This can be useful for fast rendering of already-projected geometry, or for fast rendering of the equirectangular projection.

# path.context([context])

If context is specified, sets the render context and returns the path generator. If the context is null, then the path generator will return an SVG path string when invoked on a given feature. If the context is non-null, the path generator will instead call methods on the specified context to render geometry. The context must implement the following methods:

  • beginPath()
  • moveTo(x, y)
  • lineTo(x, y)
  • arc(x, y, radius, startAngle, endAngle)
  • closePath()

Note that this is a subset of the canvas element’s 2D rendering context, and thus a canvas context can be passed to the path generator, in which case geometry will be rendered directly to the canvas. If context is not specified, returns the current render context, which defaults to null.

# path.area(feature)

Computes the projected area (in square pixels) for the specified feature. Point, MultiPoint, LineString and MultiLineString features have zero area. For Polygon and MultiPolygon features, this method first computes the area of the exterior ring, and then subtracts the area of any interior holes. This method observes any clipping and resampling performed by the projection stream.

# path.centroid(feature)

Computes the projected centroid (in pixels) for the specified feature. This is handy for, say, labeling state or county boundaries, or displaying a symbol map. The noncontiguous cartogram example scales each state around its centroid. This method observes any clipping and resampling performed by the projection stream.

# path.bounds(feature)

Computes the projected bounding box (in pixels) for the specified feature. The bounding box is represented by a two-dimensional array: [[left, top], [right, bottom]] , different from GIS geo.bounds' convention. This is handy for, say, zooming in to a particular feature. This method observes any clipping and resampling performed by the projection stream.

# path.pointRadius([radius])

If radius is specified, sets the radius used to display Point and MultiPoint features to the specified number. If radius is not specified, returns the current radius. While the radius is commonly specified as a number constant, it may also be specified as a function which is computed per feature, being passed the feature and index arguments from the path function. For example, if your GeoJSON data has additional properties, you might access those properties inside the radius function to vary the point size; alternatively, you could d3.svg.symbol and a projection for more control over the display.

Shape Generators

Note: to generate a great arc in D3, simply pass a LineString-type geometry object to d3.geo.path. D3’s projections use great-arc interpolation for intermediate points (with adaptive resampling), so there’s no need to use a shape generator to create great arcs.

# d3.geo.graticule

Constructs a feature generator for creating graticules.

# graticule()

Returns a MultiLineString geometry object representing all meridians and parallels for this graticule.

# graticule.lines()

Returns an array of LineString geometry objects, one for each meridian or parallel for this graticule.

# graticule.outline()

Returns a Polygon geometry object representing the outline of this graticule, i.e. along the meridians and parallels defining its extent.

# graticule.extent(extent)

If extent is specified, sets the major and minor extents of this graticule. If extent is not specified, returns the current minor extent, which defaults to ⟨⟨-180°, -80° - ε⟩, ⟨180°, 80° + ε⟩⟩.

# graticule.majorExtent(extent)

If extent is specified, sets the major extent of this graticule. If extent is not specified, returns the current major extent, which defaults to ⟨⟨-180°, -90° + ε⟩, ⟨180°, 90° - ε⟩⟩.

# graticule.minorExtent(extent)

If extent is specified, sets the minor extent of this graticule. If extent is not specified, returns the current minor extent, which defaults to ⟨⟨-180°, -80° - ε⟩, ⟨180°, 80° + ε⟩⟩.

# graticule.step(step)

If step is specified, sets the major and minor step for this graticule. If step is not specified, returns the current minor step, which defaults to ⟨10°, 10°⟩.

# graticule.majorStep(step)

If step is specified, sets the major step for this graticule. If step is not specified, returns the current major step, which defaults to ⟨90°, 360°⟩.

# graticule.minorStep(step)

If step is specified, sets the minor step for this graticule. If step is not specified, returns the current minor step, which defaults to ⟨10°, 10°⟩.

# graticule.precision(precision)

If precision is specified, sets the precision for this graticule, in degrees. If precision is not specified, returns the current precision, which defaults to 2.5°.

# d3.geo.circle

Constructs a feature generator for creating circles centered at a given geographic location with a given radius in degrees.

# circle(arguments…)

Returns a GeoJSON Polygon approximating a circle. The origin accessor specifies how to determine the origin for the given arguments; the default accessor uses the constant ⟨0°,0°⟩.

# circle.origin([origin])

If origin is specified, sets the circle origin. A two-element coordinate array should be specified, or an accessor function. If origin is not specified, returns the current origin, which defaults to ⟨0°,0°⟩.

# circle.angle([angle])

If angle is specified, sets the angular radius of the circle in degrees. If angle is not specified, returns the current radius, which defaults to 90°.

# circle.precision([precision])

If precision is specified, sets the precision of the interpolated circle segments in degrees. These interpolated segments are inserted when a feature is clipped by the circle. If precision is not specified, returns the current precision, which defaults to 6°.

Spherical Math

# d3.geo.area(feature)

Returns the spherical area of the specified feature in steradians. See also path.area, which computes the projected area on the Cartesian plane.

# d3.geo.centroid(feature)

Returns the spherical centroid of the specified feature. See also path.centroid, which computes the projected centroid on the Cartesian plane.

# d3.geo.bounds(feature)

Returns the spherical bounding box for the specified feature. The bounding box is represented by a two-dimensional array: [​[left, bottom], [right, top]​], where left is the minimum longitude, bottom is the minimum latitude, right is maximum longitude, and top is the maximum latitude. See also path.bounds, which computes the projected bounding box on the Cartesian plane.

# d3.geo.distance(a, b)

Returns the great-arc distance in radians between the two points a and b. Each point is specified as an array [longitude, latitude], with coordinates expressed in decimal degrees.

# d3.geo.length(feature)

Returns the great-arc length of the specified feature in radians. For polygons, returns the perimeter of the exterior ring plus that of any interior rings.

# d3.geo.interpolate(a, b)

Returns an interpolator given the two locations a and b. Each location must be represented as a two-element array of [longitude, latitude]. The returned interpolator is a function which takes a single parameter t as input, where t ranges from 0 to 1. A value of 0 returns the location a, while a value of 1 returns the location b. Intermediate values interpolate from a to b along the spanning great arc.

# d3.geo.rotation(rotate)

Specifies a rotation in the form of an array, [λ, φ, γ]. The elements of the array are angles in degrees, and specify a rotation in the following order: longitudinal, latitudinal and about the origin. If the last element of the array, γ, is omitted, this defaults to 0. Returns a function, which rotates a given location as described below.

# rotation(location)

Rotates a given location according to the angles specified for this rotation, in the order described above. A location is specified as an array [longitude, latitude], with coordinates expressed in degrees. Returns a new array representing the rotated location.

# rotation.invert(location)

Rotates a given location according to the angles specified for this rotation, but with the order described above reversed. A location is specified as an array [longitude, latitude], with coordinates expressed in degrees. Returns a new array representing the rotated location.