# Projections

Projections transform spherical polygonal geometry to planar polygonal geometry. D3 provides implementations of several classes of standard projections:

For more projections, see d3-geo-projection and d3-geo-polygon. You can implement custom projections using geoProjection or geoProjectionMutator.

*projection*(*point*)

Source · Returns a new array [*x*, *y*] (typically in pixels) representing the projected point of the given *point*. The point must be specified as a two-element array [*longitude*, *latitude*] in degrees. May return null if the specified *point* has no defined projected position, such as when the point is outside the clipping bounds of the projection.

*projection*.invert(*point*)

Source · Returns a new array [*longitude*, *latitude*] in degrees representing the unprojected point of the given projected *point*. The point must be specified as a two-element array [*x*, *y*] (typically in pixels). May return null if the specified *point* has no defined projected position, such as when the point is outside the clipping bounds of the projection.

This method is only defined on invertible projections.

*projection*.stream(*stream*)

Source · Returns a projection stream for the specified output *stream*. Any input geometry is projected before being streamed to the output stream. A typical projection involves several geometry transformations: the input geometry is first converted to radians, rotated on three axes, clipped to the small circle or cut along the antimeridian, and lastly projected to the plane with adaptive resampling, scale and translation.

*projection*.preclip(*preclip*)

If *preclip* is specified, sets the projection’s spherical clipping to the specified function and returns the projection; *preclip* is a function that takes a projection stream and returns a clipped stream. If *preclip* is not specified, returns the current spherical clipping function. Preclipping is commonly used to cut along the antimeridian line or along a small circle.

*projection*.postclip(*postclip*)

If *postclip* is specified, sets the projection’s Cartesian clipping to the specified function and returns the projection; *postclip* is a function that takes a projection stream and returns a clipped stream. If *postclip* is not specified, returns the current Cartesian clipping function. Post-clipping occurs on the plane, when a projection is bounded to a certain extent such as a rectangle.

*projection*.clipAngle(*angle*)

Source · If *angle* is specified, sets the projection’s clipping circle radius to the specified angle in degrees and returns the projection. If *angle* is null, switches to antimeridian cutting rather than small-circle clipping. If *angle* is not specified, returns the current clip angle which defaults to null. Small-circle clipping is independent of viewport clipping via *projection*.clipExtent. See also *projection*.preclip, geoClipAntimeridian, geoClipCircle.

*projection*.clipExtent(*extent*)

Source · If *extent* is specified, sets the projection’s viewport clip extent to the specified bounds in pixels and returns the projection. The *extent* bounds are specified as an array [[*x₀*, *y₀*], [*x₁*, *y₁*]], where *x₀* is the left-side of the viewport, *y₀* is the top, *x₁* is the right and *y₁* is the bottom. If *extent* is null, no viewport clipping is performed. If *extent* is not specified, returns the current viewport clip extent which defaults to null. Viewport clipping is independent of small-circle clipping via *projection*.clipAngle. See also *projection*.postclip, geoClipRectangle.

*projection*.scale(*scale*)

Source · If *scale* is specified, sets the projection’s scale factor to the specified value and returns the projection. If *scale* is not specified, returns the current scale factor; the default scale is projection-specific. The scale factor corresponds linearly to the distance between projected points; however, absolute scale factors are not equivalent across projections.

*projection*.translate(*translate*)

Source · If *translate* is specified, sets the projection’s translation offset to the specified two-element array [*t _{x}*,

*t*] and returns the projection. If

_{y}*translate*is not specified, returns the current translation offset which defaults to [480, 250]. The translation offset determines the pixel coordinates of the projection’s center. The default translation offset places ⟨0°,0°⟩ at the center of a 960×500 area.

*projection*.center(*center*)

Source · If *center* is specified, sets the projection’s center to the specified *center*, a two-element array of [*longitude*, *latitude*] in degrees and returns the projection. If *center* is not specified, returns the current center, which defaults to ⟨0°,0°⟩.

*projection*.angle(*angle*)

Source · If *angle* is specified, sets the projection’s post-projection planar rotation angle to the specified *angle* in degrees and returns the projection. If *angle* is not specified, returns the projection’s current angle, which defaults to 0°. Note that it may be faster to rotate during rendering (e.g., using *context*.rotate) rather than during projection.

*projection*.reflectX(*reflect*)

If *reflect* is specified, sets whether or not the *x*-dimension is reflected (negated) in the output. If *reflect* is not specified, returns true if *x*-reflection is enabled, which defaults to false. This can be useful to display sky and astronomical data with the orb seen from below: right ascension (eastern direction) will point to the left when North is pointing up.

*projection*.reflectY(*reflect*)

If *reflect* is specified, sets whether or not the *y*-dimension is reflected (negated) in the output. If *reflect* is not specified, returns true if *y*-reflection is enabled, which defaults to false. This is especially useful for transforming from standard spatial reference systems, which treat positive *y* as pointing up, to display coordinate systems such as Canvas and SVG, which treat positive *y* as pointing down.

*projection*.rotate(*angles*)

Source · If *angles* is specified, sets the projection’s three-axis spherical rotation to the specified value, which must be a two- or three-element array of numbers [*lambda*, *phi*, *gamma*] specifying the rotation angles in degrees about each spherical axis. (These correspond to yaw, pitch and roll.) If the rotation angle *gamma* is omitted, it defaults to 0. See also geoRotation. If *angles* is not specified, returns the current rotation which defaults to [0, 0, 0].

*projection*.precision(*precision*)

Source · If *precision* is specified, sets the threshold for the projection’s adaptive resampling to the specified value in pixels and returns the projection. This value corresponds to the Douglas–Peucker distance. If *precision* is not specified, returns the projection’s current resampling precision which defaults to √0.5 ≅ 0.70710…

*projection*.fitExtent(*extent*, *object*)

Source · Sets the projection’s scale and translate to fit the specified GeoJSON *object* in the center of the given *extent*. The extent is specified as an array [[x₀, y₀], [x₁, y₁]], where x₀ is the left side of the bounding box, y₀ is the top, x₁ is the right and y₁ is the bottom. Returns the projection.

For example, to scale and translate the New Jersey State Plane projection to fit a GeoJSON object *nj* in the center of a 960×500 bounding box with 20 pixels of padding on each side:

```
var projection = d3.geoTransverseMercator()
.rotate([74 + 30 / 60, -38 - 50 / 60])
.fitExtent([[20, 20], [940, 480]], nj);
```

Any clip extent is ignored when determining the new scale and translate. The precision used to compute the bounding box of the given *object* is computed at an effective scale of 150.

*projection*.fitSize(*size*, *object*)

Source · A convenience method for *projection*.fitExtent where the top-left corner of the extent is [0, 0]. The following two statements are equivalent:

```
projection.fitExtent([[0, 0], [width, height]], object);
projection.fitSize([width, height], object);
```

*projection*.fitWidth(*width*, *object*)

Source · A convenience method for *projection*.fitSize where the height is automatically chosen from the aspect ratio of *object* and the given constraint on *width*.

*projection*.fitHeight(*height*, *object*)

Source · A convenience method for *projection*.fitSize where the width is automatically chosen from the aspect ratio of *object* and the given constraint on *height*.

## Raw projections

Raw projections are point transformation functions that are used to implement custom projections; they typically passed to geoProjection or geoProjectionMutator. They are exposed here to facilitate the derivation of related projections. Raw projections take spherical coordinates [*lambda*, *phi*] in radians (not degrees!) and return a point [*x*, *y*], typically in the unit square centered around the origin.

*project*(*lambda*, *phi*)

Projects the specified point [*lambda*, *phi*] in radians, returning a new point [*x*, *y*] in unitless coordinates.

*project*.invert(*x*, *y*)

The inverse of *project*.

## geoProjection(*project*)

Source · Constructs a new projection from the specified raw projection, *project*. The *project* function takes the *longitude* and *latitude* of a given point in radians, often referred to as *lambda* (λ) and *phi* (φ), and returns a two-element array [*x*, *y*] representing its unit projection. The *project* function does not need to scale or translate the point, as these are applied automatically by *projection*.scale, *projection*.translate, and *projection*.center. Likewise, the *project* function does not need to perform any spherical rotation, as *projection*.rotate is applied prior to projection.

For example, a spherical Mercator projection can be implemented as:

```
var mercator = d3.geoProjection(function(x, y) {
return [x, Math.log(Math.tan(Math.PI / 4 + y / 2))];
});
```

If the *project* function exposes an *invert* method, the returned projection will also expose *projection*.invert.

## geoProjectionMutator(*factory*)

Source · Constructs a new projection from the specified raw projection *factory* and returns a *mutate* function to call whenever the raw projection changes. The *factory* must return a raw projection. The returned *mutate* function returns the wrapped projection. For example, a conic projection typically has two configurable parallels. A suitable *factory* function, such as geoConicEqualAreaRaw, would have the form:

```
// y0 and y1 represent two parallels
function conicFactory(phi0, phi1) {
return function conicRaw(lambda, phi) {
return […, …];
};
}
```

Using d3.geoProjectionMutator, you can implement a standard projection that allows the parallels to be changed, reassigning the raw projection used internally by geoProjection:

```
function conicCustom() {
var phi0 = 29.5,
phi1 = 45.5,
mutate = d3.geoProjectionMutator(conicFactory),
projection = mutate(phi0, phi1);
projection.parallels = function(_) {
return arguments.length ? mutate(phi0 = +_[0], phi1 = +_[1]) : [phi0, phi1];
};
return projection;
}
```

When creating a mutable projection, the *mutate* function is typically not exposed.

## geoTransform(*methods*)

Source · Defines an arbitrary transform using the methods defined on the specified *methods* object. Any undefined methods will use pass-through methods that propagate inputs to the output stream.

For example, to reflect the *y*-dimension (see also *projection*.reflectY):

```
const reflectY = d3.geoTransform({
point(x, y) {
this.stream.point(x, -y);
}
});
```

Or to define an affine matrix transformation:

```
function matrix(a, b, c, d, tx, ty) {
return d3.geoTransform({
point(x, y) {
this.stream.point(a * x + b * y + tx, c * x + d * y + ty);
}
});
}
```

A transform is a generalized projection; it implements *projection*.stream and can be passed to *path*.projection. However, it implements only a subset of the other projection methods, and represent arbitrary geometric transformations rather than projections from spherical to planar coordinates.

## geoIdentity()

Source · The identity transform can be used to scale, translate and clip planar geometry. It implements *projection*.scale, *projection*.translate, *projection*.fitExtent, *projection*.fitSize, *projection*.fitWidth, *projection*.fitHeight, *projection*.clipExtent, *projection*.angle, *projection*.reflectX and *projection*.reflectY.

## geoClipAntimeridian

Source · A clipping function which transforms a stream such that geometries (lines or polygons) that cross the antimeridian line are cut in two, one on each side. Typically used for pre-clipping.

## geoClipCircle(*angle*)

Source · Generates a clipping function which transforms a stream such that geometries are bounded by a small circle of radius *angle* around the projection’s center. Typically used for pre-clipping.

## geoClipRectangle(*x0*, *y0*, *x1*, *y1*)

Source · Generates a clipping function which transforms a stream such that geometries are bounded by a rectangle of coordinates [[*x0*, *y0*], [*x1*, *y1*]]. Typically used for post-clipping.