Skip to content

Retrieval data types

Multiple functions are available to serialize the Topology object. All of them are shown in this table below including the required hard and soft dependencies and further described below.

Functions Required Packages
topojson.Topology().to_json() Shapely, NumPy
topojson.Topology().to_dict() Shapely, NumPy
topojson.Topology().to_svg() Shapely, NumPy
topojson.Topology().to_geojson() Shapely, NumPy
topojson.Topology().to_alt() Shapely, NumPy, Altair*
topojson.Topology().to_gdf() Shapely, NumPy, GeoPandas*
topojson.Topology().to_polars() Shapely, NumPy, Polars*
topojson.Topology().to_widget() Shapely, NumPy, Altair*, Simplification*, ipywidgets*

* optional dependencies

Note: Only the serialization to different output types is described here. See 'settings and tuning' for detailed examples of all options regarding creating the Topology object.

  1. .to_json()
  2. .to_dict()
  3. .to_svg()
  4. .to_geojson()
  5. .to_alt()
  6. .to_gdf()
  7. .to_polars()
  8. .to_widget()

.to_json()

Serialize the Topology object into JSON. This is what is called TopoJSON.

Example

Given the following two polygons:

import topojson as tp
from shapely import geometry

data = [
    {"type": "Polygon", "coordinates": [[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]]},
    {"type": "Polygon", "coordinates": [[[1, 0], [2, 0], [2, 1], [1, 1], [1, 0]]]}
]
geometry.GeometryCollection([geometry.shape(g) for g in data])

The Topology can be computed

topo = tp.Topology(data)

And serialized and saved into a JSON (TopoJSON) file:

topo.to_json('my_file.topo.json')

To inspect the JSON object first, leave out the filepath (fp) argument.

print(topo.to_json())

{"type":"Topology","objects":{"data":{"geometries":[{"type":"Polygon","arcs":[[-2,0]],"id":0},{"type":"Polygon","arcs":[[1,2]],"id":1}],"type":"GeometryCollection"}},"bbox":[0.0,0.0,2.0,1.0],"transform":{"scale":[2.000020000200002e-05,1.000010000100001e-05],"translate":[0.0,0.0]},"arcs":[[[50000,0],[-50000,0],[0,99999],[50000,0]],[[50000,0],[0,99999]],[[50000,99999],[49999,0],[0,-99999],[-49999,0]]]}
Default is a compact form of JSON. If you like a more readable format, set pretty=True.
print(topo.to_json(pretty=True))

{
    "type": "Topology",
    "objects": {
        "data": {
            "geometries": [
                {"type": "Polygon", "arcs": [[-2, 0]], "id": 0},
                {"type": "Polygon", "arcs": [[1, 2]], "id": 1}
            ],
            "type": "GeometryCollection"
        }
    },
    "bbox": [0.0, 0.0, 2.0, 1.0],
    "transform": {
        "scale": [2.000020000200002e-05, 1.000010000100001e-05], "translate": [0.0, 0.0]
    },
    "arcs": [
        [[50000, 0], [-50000, 0], [0, 99999], [50000, 0]], [[50000, 0], [0, 99999]],
        [[50000, 99999], [49999, 0], [0, -99999], [-49999, 0]]
    ]
}
The pretty option depends on the setting indent and maxlinelength, these default to 4 and 88 respectively.


.to_dict()

Serialize the Topology object into a Python Dictionary.

Example

We use the data as is prepared in the .to_json() section.

topo.to_dict()

{'type': 'Topology',
 'objects': {'data': {'geometries': [{'type': 'Polygon', 'arcs': [[-2, 0]], 'id': 0},
                                     {'type': 'Polygon', 'arcs': [[1, 2]], 'id': 1}],
                      'type': 'GeometryCollection'}},
 'bbox': (0.0, 0.0, 2.0, 1.0),
 'transform': {'scale': [2.000020000200002e-05, 1.000010000100001e-05],
               'translate': [0.0, 0.0]},
 'arcs': [[[50000, 0], [-50000, 0], [0, 99999], [50000, 0]],
          [[50000, 0], [0, 99999]],
          [[50000, 99999], [49999, 0], [0, -99999], [-49999, 0]]]}
In the computation of the Topology object a few options are adopted. To include these options in the Python Dictionary use options=True.

topo.to_dict(options=True)

{'type': 'Topology',
 'objects': {'data': {'geometries': [{'type': 'Polygon', 'arcs': [[-2, 0]], 'id': 0},
                                     {'type': 'Polygon', 'arcs': [[1, 2]], 'id': 1}],
                      'type': 'GeometryCollection'}},
 'bbox': (0.0, 0.0, 2.0, 1.0),
 'transform': {'scale': [2.000020000200002e-05, 1.000010000100001e-05],
               'translate': [0.0, 0.0]},
 'arcs': [[[50000, 0], [-50000, 0], [0, 99999], [50000, 0]],
          [[50000, 0], [0, 99999]],
          [[50000, 99999], [49999, 0], [0, -99999], [-49999, 0]]],
 'options': {'topology': True,
             'prequantize': True,
             'topoquantize': False,
             'presimplify': False,
             'toposimplify': False,
             'shared_coords': False,
             'prevent_oversimplify': True,
             'simplify_with': 'shapely',
             'simplify_algorithm': 'dp',
             'winding_order': 'CW_CCW',
             'object_name': ['data'],
             'ignore_index': False}}
With state=True, also the hash of the input geometry of each feature (source_hashes) is included, so that the Topology can be read back with Topology.read_json and updated, see incremental updates. The same applies to .to_json().


.to_svg()

Serialize the Topology object into a visual Support Vector Graphic (SVG) mesh.

Example

We use the data as is prepared in the .to_json() section.

topo.to_svg()

The output is a mesh and information of polygons are not included. To draw each captured linestring separate use separate=True.

topo.to_svg(separate=True)


.to_geojson()

Serialize the Topology object into GeoJSON. This destroys the Topology.

Example

We use the data as is prepared in the .to_json() section.

Serialize and save into a JSON (GeoJSON) file

topo.to_geojson('my_file.geo.json')

To inspect the JSON object first, leave out the filepath (fp) argument.

print(topo.to_geojson())

{"type":"FeatureCollection","features":[{"id":0,"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[1.000010000100001,1.0],[0.0,1.0],[0.0,0.0],[1.000010000100001,0.0],[1.000010000100001,1.0]]]}},{"id":1,"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[1.000010000100001,0.0],[2.0,0.0],[2.0,1.0],[1.000010000100001,1.0],[1.000010000100001,0.0]]]}}]}
Default is a compact form of JSON. If you like a more readable format, set pretty=True.
print(topo.to_geojson(pretty=True))

{
    "type": "FeatureCollection",
    "features": [
        {
            "id": 0,
            "type": "Feature",
            "properties": {},
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [1.000010000100001, 1.0], [0.0, 1.0], [0.0, 0.0], [1.000010000100001, 0.0],
                        [1.000010000100001, 1.0]
                    ]
                ]
            }
        },
        {
            "id": 1,
            "type": "Feature",
            "properties": {},
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [1.000010000100001, 0.0], [2.0, 0.0], [2.0, 1.0], [1.000010000100001, 1.0],
                        [1.000010000100001, 0.0]
                    ]
                ]
            }
        }
    ]
}
The pretty option depends on the setting indent and maxlinelength, these default to 4 and 88 respectively.

More options in generating the GeoJSON from the computed Topology are validate (True or False), winding_order and decimals and object_name. Where the TopoJSON standard defines a winding order of clock-wise orientation for outer polygons and counter-clockwise orientation for inner polygons is the winding order in the GeoJSON standard the opposite (CCW_CW). The decimals option defines the number of decimals for the output coordinates. With the option object_name it is possible to specify which object you want to serialize to GeoJSON (in case of multiple objects in the input data), defaults to index 0.


.to_alt()

Serialize the Topology object into an Altair visualization. Altair is an optional dependency and not automatically installed.

Example

Here we load continental Africa as data file and apply a simplification on the arcs after the topology is computed using toposimplify.

import topojson as tp
data = tp.utils.example_data_africa()

topo = tp.Topology(data, toposimplify=4)

Using .to_alt() function one can visualize the Topology using Altair. This means that the TopoJSON as data-object is included in the Vega-Lite specification generated by Altair.

The default will render the Topology as a mesh, meaning that within Vega-Lite the TopoJSON input is rendered as a single unified MultiLineString GeoJSON instance. By default no projection is applied meaning that the input is rendered in a cartesian coordinate system

# this requires the (optional!) package Altair.
topo.to_alt()

A few more convenience options are included for Altair visualizations, such as assigning a color property for individual features and using geographic projections and defining the object_name. With the option object_name it is possible to specify which object you want to serialize to Altair (in case of multiple objects in the input data), defaults to index 0.

Per TopoJSON specification, information of individual features are stored as an nested object within properties. For example here is shown the properties of the feature at index-0:

topo.to_dict()['objects']['data']['geometries'][0]
{'id': 0,
 'type': 'Polygon',
 'properties': {'continent': 'Africa',
                'gdp_md_est': 150600.0,
                'iso_a3': 'TZA',
                'name': 'Tanzania',
                'pop_est': 53950935},
 'bbox': (29.339997592900346,
          -11.720938002166735,
          40.31659000000002,
          -0.9500000000000001),
 'arcs': [[-6, 0, -84, -82, -77, -3, -100, -140, -137]]}

Next, we map the property name of each feature as color property using a nominal (:N) encoding type. The equalEarth is used as geographic projection. By default tooltips are enabled.

# this requires the (optional!) package Altair.
topo.to_alt(color='properties.name:N', projection='equalEarth')

Note: Type encoding needs to be specified and cannot be automatically inferred from TopoJSON input data.


.to_gdf()

Serialize the Topology object into a GeoPandas GeoDataFrame. This destroys the Topology. GeoPandas is an optional dependency and not automatically installed. With the option object_name it is possible to specify which object you want to serialize into a GeoDataFrame using the object_name (in case of multiple objects in the input data), defaults to index 0.

Note: There is no winding-order enforcement in the OGR model; so the Fiona/OGR TopoJSON driver is NOT used in this routine, but the .to_geojson() function.

Example

Given the included example data set of continental Africa and application of the Topology

import topojson as tp

data = tp.utils.example_data_africa()

topo = tp.Topology(data)

# this requires the (optional!) package GeoPandas.
topo.to_gdf().head(3)
topo.to_gdf().plot()

geometry continent gdp_md_est iso_a3 name pop_est
0 POLYGON ((33.90340176420759 -0.9498405139637072,... Africa 150600.0 TZA Tanzania 53950935
1 POLYGON ((-8.665666773160552 27.65613579897171, ... Africa 906.5 ESH W. Sahara 603253
2 POLYGON ((29.339827093193016 -4.499877032452222,... Africa 66010.0 COD Dem. Rep. Congo 83301151


.to_polars()

Serialize the Topology object into a Polars DataFrame: the id and the properties as columns, and the geometry as WKB in the column geometry, as polars-st stores it. With a CRS that has an EPSG code, from the input or given with crs, the WKB is EWKB with this code as SRID, so that polars-st knows the CRS. Polars is an optional dependency and not automatically installed. The ids of the features are the column id, so ids that went in (a column id of a Polars DataFrame, the index of a GeoDataFrame, the ids of GeoJSON features) come out as they went in. As with to_gdf(), object_name selects the object.

Example

import polars_st as st
import topojson as tp

data = tp.utils.example_data_africa()
topo = tp.Topology(data)

# this requires the (optional!) package Polars, here with polars-st
gdf = st.GeoDataFrame(topo.to_polars(crs="EPSG:4326"))
print(gdf.select("name", "pop_est", st.geom().st.to_wkt()).head(3))
shape: (3, 3)
┌─────────────────┬──────────┬─────────────────────────────────┐
│ name            ┆ pop_est  ┆ geometry                        │
│ ---             ┆ ---      ┆ ---                             │
│ str             ┆ i64      ┆ str                             │
╞═════════════════╪══════════╪═════════════════════════════════╡
│ Tanzania        ┆ 53950935 ┆ POLYGON ((33.903402 -0.949841,… │
│ W. Sahara       ┆ 603253   ┆ POLYGON ((-8.665667 27.656136,… │
│ Dem. Rep. Congo ┆ 83301151 ┆ POLYGON ((29.339827 -4.499877,… │
└─────────────────┴──────────┴─────────────────────────────────┘

.to_widget()

Serialize the Topology object into an interactive IPython Widget. This requires the optional packages simplification, altair and ipywidgets. These are not installed automatically.

The sliders set the tolerance of toposimplify and the topoquantize factor. With an algorithm share of vertices (Douglas-Peucker or Visvalingam-Whyatt), the slider Keep share sets the share of the vertices to keep instead (toposimplify(keep=...)).

Example

Given the included example data set of continental Africa, one can enable the interactive IPython Widget as follow

import topojson as tp

data = tp.utils.example_data_africa()

topo = tp.Topology(data, prevent_oversimplify=False)

# this requires the (optional!) packages: simplification, altair & ipywidgets.
topo.to_widget()

IPyWidget Africa

Try it in your browser. Here topojson runs in your browser, in Pyodide (Python in WebAssembly). The slider keep sets the share of the vertices that Douglas-Peucker keeps (toposimplify(keep=...)); below it is the tolerance epsilon that gives the same result.

Note: prevent_oversimplify is set to False since the Douglas-Peucker algorithm within simplification can not prevent oversimplification.

Custom slider options can be set using the slider_toposimplify and slider_topoquantize parameter settings.