Types of input data¶
This library can be useful for you if you have if one of the following geographical input data:
- GeoDataFrame or GeoSeries
- Polars DataFrame or Series
- GeoJSON data from file
- TopoJSON data from file
- FeatureCollection or Features
- fiona.Collection
shapely.geometryobject- object that support the
__geo_interface__ listof objects that provide a valid__geo_interface__or can be parsed into onedictof objects that provide a valid__geo_interface__or can be parsed into onelistof GeoDataFrameslistof GeoJSON objects
GeoDataFrame or GeoSeries¶
From the package geopandas (not a hard dependency). The index becomes the id of
each feature. A row can hold any geometry type, also a GeometryCollection.
Example
import topojson as tp
import geopandas
from shapely import geometry
%matplotlib inline
gdf = geopandas.GeoDataFrame({
"name": ["abc", "def"],
"geometry": [
geometry.Polygon([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]),
geometry.Polygon([[1, 0], [2, 0], [2, 1], [1, 1], [1, 0]])
]
})
gdf.plot(column="name")
gdf.head()
| name | geometry | |
|---|---|---|
| 0 | abc | POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0)) |
| 1 | def | POLYGON ((1 0, 2 0, 2 1, 1 1, 1 0)) |
tp.Topology(gdf, prequantize=False).to_json(pretty=True)
{
"type": "Topology",
"objects": {
"data": {
"geometries": [
{"properties": {"name": "abc"}, "type": "Polygon", "arcs": [[-2, 0]], "id": 0},
{"properties": {"name": "def"}, "type": "Polygon", "arcs": [[1, 2]], "id": 1}
],
"type": "GeometryCollection"
}
},
"bbox": [0.0, 0.0, 2.0, 1.0],
"arcs": [
[[1.0, 0.0], [0.0, 0.0], [0.0, 1.0], [1.0, 1.0]], [[1.0, 0.0], [1.0, 1.0]],
[[1.0, 1.0], [2.0, 1.0], [2.0, 0.0], [1.0, 0.0]]
]
}
Polars DataFrame or Series¶
From the package polars (not a hard dependency), such as a GeoDataFrame of
polars-st: a DataFrame with a column of
geometries as WKB or EWKB (Binary). The column geometry is used, or else the only
Binary column; a column id gives the ids of the features, as the index of a
GeoDataFrame, and the other columns become the properties. A Series of WKB works as
well, and a list of DataFrames with object_name, as for GeoDataFrames. If the
geometries share an SRID (EWKB), it becomes the CRS, also of to_gdf().
Example
import polars_st as st
import topojson as tp
gdf = st.GeoDataFrame({
"name": ["abc", "def"],
"geometry": [
"POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))",
"POLYGON ((1 0, 2 0, 2 1, 1 1, 1 0))",
],
})
topo = tp.Topology(gdf, prequantize=False)
print(topo.to_json(pretty=True))
{
"type": "Topology",
"objects": {
"data": {
"geometries": [
{"properties": {"name": "abc"}, "type": "Polygon", "arcs": [[-2, 0]], "id": 0},
{"properties": {"name": "def"}, "type": "Polygon", "arcs": [[1, 2]], "id": 1}
],
"type": "GeometryCollection"
}
},
"bbox": [0.0, 0.0, 2.0, 1.0],
"arcs": [
[[1.0, 0.0], [0.0, 0.0], [0.0, 1.0], [1.0, 1.0]], [[1.0, 0.0], [1.0, 1.0]],
[[1.0, 1.0], [2.0, 1.0], [2.0, 0.0], [1.0, 0.0]]
]
}
GeoJSON data from file¶
A GeoJSON file can be parsed as json dictionary.
Example
import topojson as tp
import json
with open("tests/files_geojson/example_data_africa.geojson", 'r') as f:
data = json.load(f)
assert data['type'] == 'FeatureCollection'
topo = tp.Topology(data)
# to visualize we use the (optional!) package Altair.
topo.toposimplify(4).to_alt()
TopoJSON data from file¶
A TopoJSON file can be post-processed using json dictionary.
Example
import topojson as tp
import json
with open("tests/files_topojson/naturalearth_lowres_africa.topojson", 'r') as f:
data = json.load(f)
# parse topojson file using `object_name`
topo = tp.Topology(data, object_name="data")
topo.toposimplify(4).to_svg()
FeatureCollection or Features¶
From the package geojson (not a hard dependency)
Example
import topojson as tp
from geojson import Feature, Polygon, FeatureCollection
feat_1 = Feature(
geometry=Polygon([[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]]),
properties={"name":"abc"}
)
feat_2 = Feature(
geometry=Polygon([[[1, 0], [2, 0], [2, 1], [1, 1], [1, 0]]]),
properties={"name":"def"}
)
fc = FeatureCollection([feat_1, feat_2])
tp.Topology(fc, prequantize=False).to_json(pretty=True)
{
"type": "Topology",
"objects": {
"data": {
"geometries": [
{
"properties": {"name": "abc"}, "type": "Polygon", "arcs": [[-2, 0]], "id": "feature_0"
},
{"properties": {"name": "def"}, "type": "Polygon", "arcs": [[1, 2]], "id": "feature_1"}
],
"type": "GeometryCollection"
}
},
"bbox": [0.0, 0.0, 2.0, 1.0],
"arcs": [
[[1.0, 0.0], [0.0, 0.0], [0.0, 1.0], [1.0, 1.0]], [[1.0, 0.0], [1.0, 1.0]],
[[1.0, 1.0], [2.0, 1.0], [2.0, 0.0], [1.0, 0.0]]
]
}
fiona.Collection¶
From the package fiona (not a hard dependency)
Example
import topojson as tp
import fiona
with fiona.open('tests/files_geojson/mesh2d.geojson') as fio_col:
topo = tp.Topology(fio_col)
topo.to_svg()
shapely.geometry object¶
From the package shapely
Example
import topojson as tp
from shapely import geometry
data = geometry.MultiLineString([
[(0, 0), (10, 0), (10, 5), (20, 5)],
[(5, 0), (25, 0), (25, 5), (16, 5), (16, 10), (14, 10), (14, 5), (0, 5)]
])
tp.Topology(data).to_svg()
object that support the __geo_interface__¶
This example use the package pyshp (not a hard dependency)
Example
import topojson as tp
import shapefile
data = shapefile.Reader("tests/files_shapefile/southamerica.shp")
topo = tp.Topology(data)
topo.toposimplify(4).to_svg()
list of objects that provide a valid __geo_interface__ or can be parsed into one¶
The list should contain items that supports the __geo_interface__
Example
import topojson as tp
list_in = [
{"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]]]}
]
tp.Topology(list_in, prequantize=False).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],
"arcs": [
[[1.0, 0.0], [0.0, 0.0], [0.0, 1.0], [1.0, 1.0]], [[1.0, 0.0], [1.0, 1.0]],
[[1.0, 1.0], [2.0, 1.0], [2.0, 0.0], [1.0, 0.0]]
]
}
dict of objects that provide a valid __geo_interface__ or can be parsed into one¶
The dictionary should be structured like {key1: obj1, key2: obj2}.
Example
import topojson as tp
dict_in = {
0: {
"type": "Polygon",
"coordinates": [[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]],
},
1: {
"type": "Polygon",
"coordinates": [[[1, 0], [2, 0], [2, 1], [1, 1], [1, 0]]],
}
}
tp.Topology(dict_in, prequantize=False).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],
"arcs": [
[[1.0, 0.0], [0.0, 0.0], [0.0, 1.0], [1.0, 1.0]], [[1.0, 0.0], [1.0, 1.0]],
[[1.0, 1.0], [2.0, 1.0], [2.0, 0.0], [1.0, 0.0]]
]
}
list of GeoDataFrames¶
From the package geopandas (not a hard dependency).
Example
import topojson as tp
import geopandas as gpd
from shapely import geometry
gdf_1 = gpd.GeoDataFrame({
"uniq_name": ["abc", "def"],
"shrd_name": ["rect", "rect"],
"geometry": [
geometry.Polygon([[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]]),
geometry.Polygon([[0, 1], [1, 1], [1, 2], [0, 2], [0, 1]])
]
})
gdf_2 = gdf_1.dissolve(by='shrd_name', as_index=False)
topo = tp.Topology(data=[gdf_1, gdf_2], object_name=['geom_1', 'geom_2'], prequantize=False)
topo.to_dict()
{'type': 'Topology',
'objects': {'geom_1': {'geometries': [{'properties': {'uniq_name': 'abc',
'shrd_name': 'rect'},
'type': 'Polygon',
'arcs': [[-1, 1]],
'id': 0},
{'properties': {'uniq_name': 'def', 'shrd_name': 'rect'},
'type': 'Polygon',
'arcs': [[0, 2]],
'id': 1}],
'type': 'GeometryCollection'},
'geom_2': {'geometries': [{'properties': {'shrd_name': 'rect',
'uniq_name': 'abc'},
'type': 'Polygon',
'arcs': [[1, 2]],
'id': 0}],
'type': 'GeometryCollection'}},
'bbox': (0.0, 1.0, 2.0, 2.0),
'arcs': [[[1.0, 2.0], [1.0, 1.0]],
[[1.0, 2.0], [2.0, 2.0], [2.0, 1.0], [1.0, 1.0]],
[[1.0, 1.0], [0.0, 1.0], [0.0, 2.0], [1.0, 2.0]]]}
topo.to_gdf(object_name='geom_2').plot(column='shrd_name')
topo.to_gdf(object_name='geom_1').plot(column='uniq_name')
list of GeoJSON objects¶
Requires geojson (not a hard dependency).
Example
import json
import topojson as tp
with open('tests/files_geojson/geojson_1.json', 'r') as gj_1:
geojson_1 = json.load(gj_1)
with open('tests/files_geojson/geojson_2.json', 'r') as gj_2:
geojson_2 = json.load(gj_2)
topo = tp.Topology(
data=[geojson_1, geojson_2],
object_name=['gjson_1', 'gjson_2']
)
print(topo.to_json(pretty=True))
{
"type": "Topology",
"objects": {
"gjson_1": {
"geometries": [
{
"id": 0,
"type": "Feature",
"properties": {"shrd_name": "rect", "uniq_name": "abc"},
"geometry": {
"type": "Polygon",
"coordinates": [[[1.0, 1.0], [2.0, 1.0], [2.0, 2.0], [1.0, 2.0], [1.0, 1.0]]]
},
"bbox": [1.0, 1.0, 2.0, 2.0],
"arcs": [[[-1, 2]]]
},
{
"id": 1,
"type": "Feature",
"properties": {"shrd_name": "rect", "uniq_name": "def"},
"geometry": {
"type": "Polygon",
"coordinates": [[[0.0, 1.0], [1.0, 1.0], [1.0, 2.0], [0.0, 2.0], [0.0, 1.0]]]
},
"bbox": [0.0, 1.0, 1.0, 2.0],
"arcs": [[[1, 0, 3]]]
}
],
"type": "GeometryCollection"
},
"gjson_2": {
"geometries": [
{
"id": 0,
"type": "Feature",
"properties": {"shrd_name": "rect", "uniq_name": "abc"},
"geometry": {
"type": "Polygon",
"coordinates": [
[[0.0, 1.0], [0.0, 2.0], [1.0, 2.0], [2.0, 2.0], [2.0, 1.0], [1.0, 1.0], [0.0, 1.0]]
]
},
"bbox": [0.0, 1.0, 2.0, 2.0],
"arcs": [[[1, 2, 3]]]
}
],
"type": "GeometryCollection"
}
},
"bbox": [0.0, 1.0, 2.0, 2.0],
"transform": {
"scale": [2.000020000200002e-05, 1.000010000100001e-05], "translate": [0.0, 1.0]
},
"arcs": [
[[50000, 99999], [0, -99999]], [[0, 0], [0, 99999], [50000, 0]],
[[50000, 99999], [49999, 0], [0, -99999], [-49999, 0]], [[50000, 0], [-50000, 0]]
]
}