TopoJSON Client
The topojson-client module provides tools for manipulating TopoJSON, such as to merge shapes or quantize coordinates, and for converting back to GeoJSON for rendering with standard tools such as d3.geoPath. For example, bl.ocks.org/3783604:
<!DOCTYPE html>
<canvas width="960" height="600"></canvas>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/topojson-client@3"></script>
<script>
var context = d3.select("canvas").node().getContext("2d"),
path = d3.geoPath().context(context);
d3.json("https://d3js.org/us-10m.v1.json", function(error, us) {
if (error) throw error;
context.beginPath();
path(topojson.mesh(us));
context.stroke();
});
</script>
This Fork
This fork of topojson-client provides some additional features over the base repository:
- It packs coordinates and arc indices into packed ArrayBuffers instead of using the standard inefficient representation of arrays of arrays of point arrays. This saves almost two orders of magnitude in memory use.
- It fixes a bug in the handling of self-touching polygons when generating the GeoJSON representation (think of a figure eight).
- It adds the splice API for combining multiple packed topologies into a single packed topology without having to generate the intermediate unpacked GeoJSON collection and unpacked topology.
Installing
If you use NPM, npm install topojson-client
. Otherwise, download the latest release. You can also load directly from UNPKG as a standalone library. AMD, CommonJS, and vanilla environments are supported. In vanilla, a topojson
global is exported:
<script src="https://unpkg.com/topojson-client@3"></script>
<script>
var feature = topojson.feature(topology, "foo");
</script>
The TopoJSON client API is implemented using ES2015 modules. In compatible environments, you can import the library as a namespace, like so:
import * as topojson from "topojson-client";
Try topojson-client in your browser.
API Reference
# topojson.feature(topology, object) <>
Returns the GeoJSON Feature or FeatureCollection for the specified object in the given topology. If the specified object is a string, it is treated as topology.objects[object]. Then, if the object is a GeometryCollection, a FeatureCollection is returned, and each geometry in the collection is mapped to a Feature. Otherwise, a Feature is returned. The returned feature is a shallow copy of the source object: they may share identifiers, bounding boxes, properties and coordinates.
Some examples:
- A point is mapped to a feature with a geometry object of type “Point”.
- Likewise for line strings, polygons, and other simple geometries.
- A null geometry object (of type null in TopoJSON) is mapped to a feature with a null geometry object.
- A geometry collection of points is mapped to a feature collection of features, each with a point geometry.
- A geometry collection of geometry collections is mapped to a feature collection of features, each with a geometry collection.
See feature-test.js for more examples.
# topojson.merge(topology, objects) <>
Returns the GeoJSON MultiPolygon geometry object representing the union for the specified array of Polygon and MultiPolygon objects in the given topology. Interior borders shared by adjacent polygons are removed. See Merging States for an example. The returned geometry is a shallow copy of the source object: they may share coordinates.
# topojson.mergeArcs(topology, objects) <>
Equivalent to topojson.merge, but returns TopoJSON rather than GeoJSON. The returned geometry is a shallow copy of the source object: they may share coordinates.
# topojson.mesh(topology[, object[, filter]]) <>
Returns the GeoJSON MultiLineString geometry object representing the mesh for the specified object in the given topology. This is useful for rendering strokes in complicated objects efficiently, as edges that are shared by multiple features are only stroked once. If object is not specified, a mesh of the entire topology is returned. The returned geometry is a shallow copy of the source object: they may share coordinates.
An optional filter function may be specified to prune arcs from the returned mesh using the topology. The filter function is called once for each candidate arc and takes two arguments, a and b, two geometry objects that share that arc. Each arc is only included in the resulting mesh if the filter function returns true. For typical map topologies the geometries a and b are adjacent polygons and the candidate arc is their boundary. If an arc is only used by a single geometry then a and b are identical. This property is useful for separating interior and exterior boundaries; an easy way to produce a mesh of interior boundaries is:
var interiors = topojson.mesh(topology, object, function(a, b) { return a !== b; });
See this county choropleth for example. Note: the a and b objects are TopoJSON objects (pulled directly from the topology), and not automatically converted to GeoJSON features as by topojson.feature.
# topojson.meshArcs(topology[, object[, filter]]) <>
Equivalent to topojson.mesh, but returns TopoJSON rather than GeoJSON. The returned geometry is a shallow copy of the source object: they may share coordinates.
# topojson.neighbors(objects) <>
Returns an array representing the set of neighboring objects for each object in the specified objects array. The returned array has the same number of elements as the input array; each element i in the returned array is the array of indexes for neighbors of object i in the input array. For example, if the specified objects array contains the features foo and bar, and these features are neighbors, the returned array will be [[1], [0]], indicating that foo is a neighbor of bar and vice versa. Each array of neighbor indexes for each object is guaranteed to be sorted in ascending order.
For a practical example, see the world map with topological coloring.
Transforms
Returns the computed bounding box of the specified topology [x₀, y₀, x₁, y₁] where x₀ is the minimum x-value, y₀ is the minimum y-value, x₁ is the maximum x-value, and y₁ is the maximum y-value. If the topology has no points and no arcs, the returned bounding box is [∞, ∞, -∞, -∞]. (This method ignores the existing topology.bbox, if any.)
# topojson.quantize(topology, transform) <>
Returns a shallow copy of the specified topology with quantized and delta-encoded arcs according to the specified transform object. If the topology is already quantized, an error is thrown. See also topoquantize.
If a quantization number n is specified instead of a transform object, the corresponding transform object is first computed using the bounding box of the topology. In this case, the quantization number n must be a positive integer greater than one which determines the maximum number of expressible values per dimension in the resulting quantized coordinates; typically, a power of ten is chosen such as 1e4, 1e5 or 1e6. If the topology does not already have a topology.bbox, one is computed using topojson.bbox.
# topojson.transform(transform) <>
If the specified transform object is non-null, returns a point transform function to remove delta-encoding and apply the transform. If the transform is null, returns the identity function.
# topojson.untransform(transform) <>
If the specified transform object is non-null, returns a point transform function to apply quantized delta-encoding and remove the transform. If the transform is null, returns the identity function. See also topojson.quantize.
# transform(point[, index])
Applies this transform function to the specified point, returning a new point with the transformed coordinates. If the specified index is truthy, the input point is treated as relative to the previous point passed to this transform, as is the case with delta-encoded arcs.
Command Line Reference
topo2geo
# topo2geo [options…] <name=file>… <>
Converts one or more TopoJSON objects from an input topology to one or more GeoJSON features. For example, to convert the “states” TopoJSON GeometryCollection object in us.json to a GeoJSON feature collection in us-states.json:
topo2geo states=us-states.json < us.json
For convenience, you can omit the object name and specify only the file name; the object name will be the basename of the file, with the directory and extension removed. For example, to convert the “states” TopoJSON GeometryCollection object in us.json to a GeoJSON feature collection in states.json:
topo2geo states.json < us.json
See also geo2topo.
To list the available object names, use --list.
# topo2geo -h
# topo2geo --help
Output usage information.
# topo2geo -V
# topo2geo --version
Output the version number.
# topo2geo -n
# topo2geo --newline-delimited
Output newline-delimited JSON, with one feature per line.
# topo2geo -i file
# topo2geo --in file
Specify the input TopoJSON file name. Defaults to “-” for stdin.
# topo2geo -l
# topo2geo --list
List the names of the objects in the input topology, and then exit. For example, this:
topo2geo -l < us.json
Will output this:
counties
states
nation
topomerge
# topomerge [options…] <target=source> [file] <>
Merges polygons (or meshes lines) from the specified source TopoJSON geometry collection object, assigning to the target object.
See also topojson.mergeArcs and topojson.meshArcs.
# topomerge -h
# topomerge --help
Output usage information.
# topomerge -V
# topomerge --version
Output the version number.
# topomerge -o file
# topomerge --out file
Specify the output TopoJSON file name. Defaults to “-” for stdout.
# topomerge -k expression
# topomerge --key expression
Specify a JavaScript expression, given a TopoJSON geometry object d and its zero-based index i in its parent collection, that determines how geometry objects are grouped before merging; each group is merged separately. For example, given a topology of U.S. counties, where the id of each county is it’s five-digit FIPS code, the county boundaries can be merged into state boundaries by using the first two digits of the county FIPS code, which represents the state FIPS code:
topomerge states=counties -k 'd.id.slice(0, 2)' < us-counties.json > us-states.json
If a key is not specified, all input geometry objects will be merged together. For example, this can be used to merge the state boundaries into a single nation boundary:
topomerge nation=states < us-states.json > us.json
# topomerge -f expression
# topomerge --filter expression
Specify a JavaScript expression that filters the input geometries before merging or meshing. In conjunction with --mesh, the expression is given two TopoJSON geometry objects a and b that represent the adjacent features for a given arc segment; if the expression evaluates truthily, the associated arc segment is retained in mesh. Otherwise, the expression is given an input TopoJSON geometry object d and its zero-based index i in its parent collection; if the expression evaluates truthily, the geometry object is retained in the merged polygon.
# topomerge --mesh
Use topojson.meshArcs instead of topojson.mergeArcs, generating a geometry collection of lines rather than polygons.
topoquantize
# topoquantize [options…] <n> [file] <>
Quantizes the coordinates of the input TopoJSON topology and delta-encodes the topology’s arcs. The quantization parameter n must be a positive integer greater than one, and determines the maximum expressible number of unique values per dimension in the resulting quantized coordinates; typically, a power of ten is chosen such as 1e4, 1e5 or 1e6. If the topology does not already have a bbox, one is computed and assigned. If the topology is already quantized, an error is thrown. See also topojson.quantize.
# topoquantize -h
# topoquantize --help
Output usage information.
# topoquantize -V
# topoquantize --version
Output the version number.
# topoquantize -o file
# topoquantize --out file
Specify the output TopoJSON file name. Defaults to “-” for stdout.