picogeojson is a Python library for reading, writing, and working with GeoJSON. It emphasizes standard compliance (RFC 7946) and ergonomics. It is a pure-Python module for ease of installation and distribution.
GeoJSON files or strings are read using fromstring()
, fromfile()
, or
fromdict()
.
picogeojson.fromstring('{"type": "Point", "coordinates": [1.0, 3.0]}')
# -> <picogeojson.map.Map object at ...>
GeoJSON objects are serialized with tostring()
, tofile()
, or todict()
.
picogeojson.tostring(
picogeojson.Point([1.0, 3.0])
)
# -> {"coordinates": [1.0, 3.0], "type": "Point"}'
All of the serialization functions accept the following options:
antimeridian_cutting
: bool: Cuts geometries at the 180th meridian so
that they plot well on standard world maps.
write_bbox
: bool: Write an optional bbox
member to the GeoJSON object.
write_crs
: bool: Write a non-standard crs
member for non-WGS84
longitude-latitude coordinates.
precision
: int: Restrict the number of decimal digits in the written
coordinates (5 results in precision of 1 meter or better for longitude-latitude
coordinates).
When reading GeoJSON, picogeojson returns a Map object, which is a container for GeoJSON. Useful methods on Map objects include:
Map.extract(geotype)
: creates a generator for geometries of type
geotype, as in
geojson = picogeojson.loads(...)
for linestring in geojson.extract(picogeojson.LineString):
print(linestring)
Map.extract_features(geotype=None, properties=None)
: similar to
Map.extract
, this extract GeoJSON features, optionally filtering by
properties.
geojson = picogeojson.loads(...)
for lake in geojson.features("Polygon", {"type": "Lake", "state": "Oregon"}):
lakes_in_oregon.append(lake)
Map.map(function, geotype)
: returns a new Map
with function applied to
every contained GeoJSON geometry of type geotype.
Map.map_features(function, geotype)
: returns a new Map
with function
applied to every contained GeoJSON feature containing geometry geotype and
matching properties.
In order to create or work with GeoJSON, picogeojson defines constructors for all GeoJSON types:
pt = picogeojson.Point([1.0, 3.5])
polygon = picogeojson.Polygon([[[100.0, 20.0], [102.0, 19.7], [102.3, 23.0],
[100.1, 22.8], [100.0, 20.0]]])
feature = picojson.Feature(polygon, {"id": "example polygon"})
When constructing geometries, picogeojson takes care of ensuring that coordinate rings are closed and oriented correctly and that coordinates are nested to the correct depth.
The following methods are available:
Type | .transform |
.map |
.flatmap |
---|---|---|---|
Point | x | - | - |
LineString | x | - | - |
Polygon | x | - | - |
MultiPoint | x | - | - |
MultiLineString | x | - | - |
MultiPolygon | x | - | - |
GeometryCollection | x | x | x |
Feature | x | x | - |
FeatureCollection | x | x | x |
.transform
operates on coordinates, returning a new geometry or feature
with a function applied to each coordinate pair.
.map
applies a function to each member of a GeometryCollection or
FeatureCollection. Features have a .map_geometry
and a .map_properties
that apply functions to the underlying geometry or properties dict,
respectively.
.flatmap
applies a function to each member of a collection, constructing a
new collection by concatenating the result of each application.
GeoJSON objects may be composed (merge()
) or split (burst()
).
points = [picogeojson.Point((1, 2)),
picogeojson.Point((3, 4)),
picogeojson.Point((5, 6))]
merged_points = picogeojson.merge(points)
# -> MultiPoint(coordinates=[(1, 2), (3, 4), (5, 6)])
split_points = picogeojson.burst(merged_points)
# -> [Point((1, 2)), Point((3, 4)), Point((5, 6))]
The following benchmarks are old and likely inaccurate.
picogeojson relies on ujson.
The read benchmark involves reading a list of earthquake features. The write benchmark involves serializing the continent of Australia.
Module | Read | Write |
---|---|---|
json | 1.49 | 2.00 |
geojson | 6.74 | same |
picogeojson | 1.63 | 0.31* |
*antimeridian cutting and polygon winding check set to False