pyTopoJSON is based on the work of Mike Bostock and it provides tools for converting GeoJSON to TopoJSON. See How to Infer Topology for details on how the topology is constructed. See also us-atlas and world-atlas for pre-built TopoJSON.
pytopojson requires:
- NumPy (>= 1.15.0)
If you already have a working installation of NumPy,
the easiest way to install pytopojson is using pip
:
pip install pytopojson
# pytopojson.topology.Topology() <>
You must create a Topology
object to compute the topology:
# Import topology
from pytopojson import topology
# Create Topology object
topology_ = topology.Topology()
# Call it using a GeoJSON (dict) object, a name for the object and a quantization value (optional)
topojson = topology_({"object_name": geojson}, quantization=quantization)
This returns a TopoJSON topology for the specified
GeoJSON objects.
The returned topology makes a shallow copy of the input objects
:
the identifier, bounding box, properties and coordinates of input objects may
be shared with the output topology.
If a quantization
parameter is specified, the input geometry is quantized
prior to computing the topology, the returned topology is quantized, and its
arcs are
delta-encoded.
Quantization is recommended to improve the quality of the topology if the
input geometry is messy (i.e., small floating point error means that
adjacent boundaries do not have identical values); typical values are powers
of ten, such as 1e4, 1e5 or 1e6.
# pytopojson.feature.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 test_feature.py for more examples.
# pytopojson.merge.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.
# pytopojson.merge.MergeArcs(topology, objects) <>
Equivalent to topojson.merge.Merge(), but returns TopoJSON rather
than GeoJSON. The returned geometry is a shallow copy of the source object
:
they may share coordinates.
# pytopojson.mesh.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:
# Import topology
from pytopojson import mesh
# Create Mesh object and filter
mesh_ = mesh.Mesh()
custom_filter = lambda x, y: x != y
interiors = mesh_(topology, object_, custom_filter)
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.Feature().
# pytopojson.mesh.MeshArcs(topology[, object[, filter]]) <>
Equivalent to topojson.mesh.Mesh(), but returns TopoJSON rather than
GeoJSON. The returned geometry is a shallow copy of the source object
: they
may share coordinates.
# pytopojson.neighbors.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.
# pytopojson.bbox.BBox(topology) <>
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.)
# pytopojson.quantize.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.BBox.
# pytopojson.transform.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.
# pytopojson.untransform.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.Quantize().
Some command-line tools are also provided:
# geo2topo [options…] [name=]file… <>
Converts one or more GeoJSON objects to an output topology. For example, to convert a GeoJSON FeatureCollection in the input file us-states.json to a TopologyJSON topology in the output file us.json:
python geo2topo.py states=us-states.json > us.json
The resulting topology has a “states” object which corresponds to the input
geometry. For convenience, you can omit the object name and specify only the
output file
name; the object name will then be the basename of the file,
with the directory and extension removed. For example, to convert the
states.json GeoJSON FeatureCollection to a TopologyJSON topology with the
“states” object in us.json:
python geo2topo.py states.json > us.json
Any properties and identifiers of input feature objects are propagated to the output. If you want to transform or filter properties, try ndjson-cli as demonstrated in Command-Line Cartography.
# geo2topo -h
# geo2topo --help
Output usage information.
# geo2topo -V
# geo2topo --version
Output the version number.
# geo2topo -o file
# geo2topo --out file
Specify the output TopoJSON file name. Defaults to “-” for stdout.
# geo2topo -q count
# geo2topo --quantization count
Specify a pre-quantization parameter. 0 disables quantization. See pytopojson.topology.Topology for a description of quantization.
# 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
:
python topo2geo.py 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
:
python topo2geo.py 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 -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:
python topo2geo.py -l < us.json
Will output this:
counties
states
nation
# topoquantize
[options…] -q [input]
<>
Quantizes the coordinates of the input TopoJSON topology and
delta-encodes
the topology’s arcs. The quantization parameter q
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
pytopojson.quantize.Quantize.
# topoquantize -h
# topoquantize --help
Output usage information.
#
topoquantize -V
# topoquantize --version
Output the version number.
#
topoquantize -i input
# topoquantize --in input
Specify the input TopoJSON. Defaults to "-" for stdin.
#
topoquantize -o output
# topoquantize --out output
Specify the output TopoJSON file name. Defaults to "-" for stdout.