Wiki ▸ [[API Reference]] ▸ [[Geo]] ▸ Geo Streams

For fast transformations of geometry without temporary copies of geometry objects, D3 uses geometry streams. The main d3.geo.stream method converts a GeoJSON input object to a stream: a series of method calls on a stream listener. In addition, D3 provides several stream transformations that wrap listeners and transform the geometry. For example, the projection.stream interface transforms spherical coordinates to Cartesian coordinates, and d3.geo.path serializes geometry to either SVG or Canvas. Internally, clipping and rotating are also implemented as stream transformations.

# d3.geo.stream(object, listener)

Streams the specified GeoJSON object to the specified stream listener. (Despite the name “stream”, these method calls are currently synchronous.) While both features and geometry objects are supported as input, the stream interface only describes the geometry, and thus additional feature properties are not visible to listeners.

Stream Listeners

Stream listeners must implement several methods to traverse geometry. Listeners are inherently stateful; the meaning of a point depends on whether the point is inside of a line, and likewise a line is distinguished from a ring by a polygon.

# listener.point(x, y[, z])

Indicates a point with the specified coordinates x and y (and optionally z). The coordinate system is unspecified and implementation-dependent; for example, projection streams require spherical coordinates in degrees as input. Outside the context of a polygon or line, a point indicates a point geometry object (Point or MultiPoint). Within a line or polygon ring, the point indicates a control point.

# listener.lineStart()

Indicates the start of a line or ring. Within a polygon, indicates the start of a ring. The first ring of a polygon is the exterior ring, and is typically clockwise. Any subsequent rings indicate holes in the polygon, and are typically counterclockwise.

# listener.lineEnd()

Indicates the end of a line or ring. Within a polygon, indicates the end of a ring. Unlike GeoJSON, the redundant closing coordinate of a ring is not indicated via point, and instead is implied via lineEnd within a polygon. Thus, the given polygon input:

{
  "type": "Polygon",
  "coordinates": [
    [[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]
  ]
}

Will produce the following series of method calls on the listener:

listener.polygonStart();
listener.lineStart();
listener.point(0, 0);
listener.point(1, 0);
listener.point(1, 1);
listener.point(0, 1);
listener.lineEnd();
listener.polygonEnd();

# listener.polygonStart()

Indicates the start of a polygon. The first line of a polygon indicates the exterior ring, and any subsequent lines indicate interior holes.

# listener.polygonEnd()

Indicates the end of a polygon.

# listener.sphere()

Indicates the sphere (the globe; the unit sphere centered at ⟨0,0,0⟩).

Stream Transforms

A stream transform wraps a stream listener, transforming the geometry before passing it along to the wrapped listener. A geographic projection is one example of a stream transform. The d3.geo.transform class provides an easy way of implementing a custom stream transform.

# d3.geo.transform(methods)

Creates a new stream transform using the specified hash of methods. The hash may contain implementations of any of the standard stream listener methods: sphere, point, lineStart, lineEnd, polygonStart and polygonEnd. Any method that is not present in the specified hash will be implemented a pass-through directly to the wrapped stream. To access the wrapped stream within a method, use this.stream. For example, to implement a simple 2D matrix transform:

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

This transform can then be used in conjunction with d3.geo.path. For example, to implement a 2D affine transform that flips the y-axis:

var path = d3.geo.path()
    .projection(matrix(1, 0, 0, -1, 0, height));

# transform.stream(listener)

Given the specified stream listener, returns a wrapped stream listener that applies this transform to any input geometry before streaming it to the wrapped listener.

# d3.geo.clipExtent()

Create a new stream transform that implements axis-aligned rectangle clipping. This is typically used to clip geometry to the viewport after projecting.

# clipExtent.extent([extent])

If extent is specified, sets the clip extent to the specified rectangle [​[x0, y0], [x1, y1]​] and returns this transform. If extent is not specified, returns the current clip extent, which defaults to [​[0, 0], [960, 500]​].