# Paths

The geographic path generator, geoPath, takes a given GeoJSON geometry or feature object and generates SVG path data string or renders to a Canvas. Paths can be used with projections or transforms, or they can be used to render planar geometry directly to Canvas or SVG.

## geoPath(*projection*, *context*)

Source · Creates a new geographic path generator with the default settings. If *projection* is specified, sets the current projection. If *context* is specified, sets the current context.

`const path = d3.geoPath(projection); // for SVG`

`const path = d3.geoPath(projection, context); // for canvas`

*path*(*object*, ...*arguments*)

Source · Renders the given *object*, 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. Any additional *arguments* are passed along to the pointRadius accessor.

To display multiple features, combine them into a feature collection:

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

Or use multiple path elements:

```
svg.selectAll()
.data(features)
.join("path")
.attr("d", d3.geoPath());
```

Separate path elements are typically slower than a single path element. However, distinct path elements are useful for styling and interaction (e.g., click or mouseover). Canvas rendering (see *path*.context) is typically faster than SVG, but requires more effort to implement styling and interaction.

*path*.area(*object*)

Source · Returns the projected planar area (typically in square pixels) for the specified GeoJSON *object*.

`path.area(california) // 17063.1671837991 px²`

Point, MultiPoint, LineString and MultiLineString geometries have zero area. For Polygon and MultiPolygon geometries, this method first computes the area of the exterior ring, and then subtracts the area of any interior holes. This method observes any clipping performed by the projection; see *projection*.clipAngle and *projection*.clipExtent. This is the planar equivalent of geoArea.

*path*.bounds(*object*)

Source · Returns the projected planar bounding box (typically in pixels) for the specified GeoJSON *object*.

`path.bounds(california) // [[18.48513821663947, 159.95146883594333], [162.7651668852596, 407.09641570706725]]`

The bounding box is represented by a two-dimensional array: [[*x₀*, *y₀*], [*x₁*, *y₁*]], where *x₀* is the minimum *x*-coordinate, *y₀* is the minimum y coordinate, *x₁* is maximum *x*-coordinate, and *y₁* is the maximum y coordinate. This is handy for, say, zooming in to a particular feature. (Note that in projected planar coordinates, the minimum latitude is typically the maximum *y*-value, and the maximum latitude is typically the minimum *y*-value.) This method observes any clipping performed by the projection; see *projection*.clipAngle and *projection*.clipExtent. This is the planar equivalent of geoBounds.

*path*.centroid(*object*)

Source · Returns the projected planar centroid (typically in pixels) for the specified GeoJSON *object*.

`path.centroid(california) // [82.08679434495191, 288.14204870673404]`

This is handy for, say, labeling state or county boundaries, or displaying a symbol map. For example, a noncontiguous cartogram might scale each state around its centroid. This method observes any clipping performed by the projection; see *projection*.clipAngle and *projection*.clipExtent. This is the planar equivalent of geoCentroid.

*path*.digits(*digits*)

Source · If *digits* is specified (as a non-negative number), sets the number of fractional digits for coordinates generated in SVG path strings.

`const path = d3.geoPath().digits(3);`

If *projection* is not specified, returns the current number of digits, which defaults to 3.

`path.digits() // 3`

This option only applies when the associated *context* is null, as when this arc generator is used to produce path data.

*path*.measure(*object*)

Source · Returns the projected planar length (typically in pixels) for the specified GeoJSON *object*.

`path.measure(california) // 825.7124297512761`

Point and MultiPoint geometries have zero length. For Polygon and MultiPolygon geometries, this method computes the summed length of all rings. This method observes any clipping performed by the projection; see *projection*.clipAngle and *projection*.clipExtent. This is the planar equivalent of geoLength.

*path*.projection(*projection*)

Source · If a *projection* is specified, sets the current projection to the specified projection.

`const path = d3.geoPath().projection(d3.geoAlbers());`

If *projection* is not specified, returns the current projection.

`path.projection() // a d3.geoAlbers instance`

The projection defaults to null, which represents the identity transformation: the input geometry is not projected and is instead rendered directly in raw coordinates. This can be useful for fast rendering of pre-projected geometry, or for fast rendering of the equirectangular projection.

The given *projection* is typically one of D3’s built-in geographic projections; however, any object that exposes a *projection*.stream function can be used, enabling the use of custom projections. See D3’s transforms for more examples of arbitrary geometric transformations.

*path*.context(*context*)

Source · If *context* is specified, sets the current render context and returns the path generator.

```
const context = canvas.getContext("2d");
const path = d3.geoPath().context(context);
```

If the *context* is null, then the path generator will return an SVG path string; 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 subset of the CanvasRenderingContext2D API:

*context*.beginPath()*context*.moveTo(*x*,*y*)*context*.lineTo(*x*,*y*)*context*.arc(*x*,*y*,*radius*,*startAngle*,*endAngle*)*context*.closePath()

If a *context* is not specified, returns the current render context which defaults to null. See also d3-path.

*path*.pointRadius(*radius*)

Source · If *radius* is specified, sets the radius used to display Point and MultiPoint geometries to the specified number.

`const path = d3.geoPath().pointRadius(10);`

If *radius* is not specified, returns the current radius accessor.

`path.pointRadius() // 10`

The radius accessor defaults to 4.5. 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 any arguments passed to the path generator. 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 symbol and a projection for greater flexibility.