Migration cheatsheet¶
Look up a familiar source-library symbol and its gometry equivalent. For a migration workflow, read Migrating to gometry. For behavior, defaults, units, errors, and output shapes, see: CRS, units & measurement, Spatial indexing & joins, Grids & geocodes, Arrays & performance, and the linked API reference.
Conventions: import gometry as gm; geom is a gometry geometry; and
idx = gm.SpatialIndex(...).
Shapely¶
Construction¶
| Shapely | gometry | Notes |
|---|---|---|
Point(x, y) |
gm.Point(x, y, crs=...) |
Under a geographic CRS, (x, y) is (lon, lat). Use z= / m= for Z/M. |
LineString(coords) |
gm.LineString(coords, z=..., m=..., crs=...) |
|
Polygon(shell, holes) |
gm.Polygon(shell, holes, crs=...) |
|
MultiPoint(...) |
gm.MultiPoint(...) |
|
MultiLineString(...) |
gm.MultiLineString(...) |
|
MultiPolygon(...) |
gm.MultiPolygon(...) |
|
GeometryCollection(...) |
gm.GeometryCollection(...) |
|
box(minx, miny, maxx, maxy) |
gm.box(minx, miny, maxx, maxy, crs=...) |
In a geographic CRS, west > east crosses the longitude seam. |
shape(geojson) |
gm.from_geojson(obj) |
GeoJSON / __geo_interface__. |
shapely.points(...) |
gm.points(lons, lats, z=..., m=..., crs=...) |
Packed array. |
| mixed array | gm.GeometryArray([...]) |
Rust-owned container for vectorized ops. |
Inspection¶
| Shapely | gometry | Notes |
|---|---|---|
geom.geom_type |
geom.geometry_type |
|
geom.bounds |
geom.bounds |
An array gives an (n, 4) matrix through arr.bounds. |
geom.has_z |
geom.has_z / geom.has_m |
|
| — | geom.coordinate_axes |
|
| — | geom.epoch |
|
geom.crs (n/a in Shapely) |
geom.crs |
|
shapely.get_coordinates(geom) |
geom.coords (list(...), .x/.y, .row_index) |
Use np.asarray(view, dtype=np.float64) for the flat matrix; view.row_index maps array coordinates to source rows. |
get_parts(...) |
geom.parts |
A scalar gives a sequence view; an array gives row-preserving Groups. |
get_rings(...) |
polygon.exterior / polygon.interiors |
These expose stored shell and hole rings. For a MultiPolygon, inspect each polygon in geom.parts; use geom.boundary() for the topological boundary of occupied support. |
str(geom) / f"{geom:.2f}" / f"{geom:x}" |
same | WKT text; .Nf/.Ng round for display, x/X hex WKB. |
bool(geom) |
same | Falsy when empty. |
match geom: case Point(x, y): |
match geom: case gm.Point(x, y): |
gometry addition — leaves carry __match_args__; Shapely 2.x has no positional match on Point. Arrays match [a, *rest]. |
Predicates¶
| Shapely | gometry |
|---|---|
a.contains(b) / shapely.contains(a, b) |
gm.contains(a, b) |
shapely.contains_properly(a, b) |
gm.contains_properly(a, b) (also gm.contains_properly(prep, b) for prepared geometries, and as an index/join predicate) |
a.within(b) / shapely.within(a, b) |
gm.within(a, b) |
a.intersects(b) / shapely.intersects(a, b) |
gm.intersects(a, b) |
a.covers(b) / a.covered_by(b) |
gm.covers(a, b) / gm.covered_by(a, b) |
a.disjoint(b) |
gm.disjoint(a, b) |
a.touches(b) / a.crosses(b) / a.overlaps(b) |
gm.touches(a, b) / gm.crosses(a, b) / gm.overlaps(a, b) |
a.equals(b) |
gm.equals(a, b) |
| normalized equality | gm.equals_exact(a.normalize(), b.normalize()) |
a.relate(b) / a.relate_pattern(b, p) |
gm.relate(a, b) / gm.relate_pattern(a, b, p) |
shapely.contains_xy(g, x, y) |
gm.contains(g, x=x, y=y) |
shapely.intersects_xy(g, x, y) |
gm.intersects(g, x=x, y=y) |
a.dwithin(b, d) |
gm.dwithin(a, b, distance, unit=…) / idx.query(..., predicate="dwithin", distance=..., unit=...) |
Measurement¶
| Shapely | gometry | Notes |
|---|---|---|
geom.area |
geom.area / geoms.area |
A GeometryCollection counts overlapping members once (the area of their union); Shapely sums member areas. |
geom.length |
geom.length / geoms.length |
For a GeometryCollection, sums every member's length or perimeter, including overlaps; Shapely agrees. |
a.distance(b) / shapely.distance(a, b) |
gm.distance(a, b) |
|
| change the metric frame / units | geom.to_crs(target) / gm.area(geom, unit=…) |
|
minimum_clearance(g) |
g.minimum_clearance() |
|
hausdorff_distance / frechet_distance |
gm.hausdorff_distance(...) / gm.frechet_distance(...) |
Planar Hausdorff uses a certified relative default; a supplied positive finite max_error is an absolute output-unit bound. Geographic Hausdorff measures point and linework supports over straight chart edges and requires max_error to be omitted. |
Constructive operations¶
| Shapely | gometry | Notes |
|---|---|---|
a.intersection(b) / shapely.intersection(a, b) / a & b |
gm.intersection(a, b) / a & b |
|
a.union(b) / shapely.union(a, b) / a | b |
gm.union(a, b) / a | b |
|
a.difference(b) / shapely.difference(a, b) / a - b |
gm.difference(a, b) / a - b |
|
a.symmetric_difference(b) / a ^ b |
gm.symmetric_difference(a, b) / a ^ b |
|
unary_union(geoms) |
gm.union_all(geoms) |
Rejects conflicting CRS. |
intersection_all(geoms) |
gm.intersection_all(geoms) |
Common region of all inputs. |
symmetric_difference_all(geoms) |
gm.symmetric_difference_all(geoms) |
Region in an odd number of inputs. |
geom.buffer(d) / shapely.buffer(geom, d) |
geom.buffer(d) |
quadrant_segments corresponds to Shapely's quad_segs and GeoPandas' resolution; miter_limit corresponds to Shapely's mitre_limit. gometry defaults to 8 segments per quadrant; GeoPandas defaults to 16, so use quadrant_segments=16 to retain that approximation. |
geom.buffer(d, single_sided=True) |
geom.buffer(abs(d), side='left') for positive d; geom.buffer(abs(d), side='right') for negative d |
Sided buffers use flat ends and honor join_style, quadrant_segments, and miter_limit; gometry expresses the side explicitly and requires a non-negative distance. |
geom.simplify(t) / shapely.simplify(geom, t) |
geom.simplify(t) |
|
geom.offset_curve(d) |
geom.offset_curve(d) |
|
| rectangle intersection | gm.intersection(g, gm.box(..., crs=g.crs, epoch=g.epoch)) |
west > east selects a seam-crossing geographic box. |
geom.convex_hull |
geom.convex_hull() |
|
concave_hull(g, ratio=...) |
geom.concave_hull(concavity=..., length_threshold=...) |
Different algorithm and knobs: concavity is an edge-length ratio, not Shapely's ratio. |
geom.centroid / geom.envelope |
g.centroid() / g.envelope() |
|
geom.point_on_surface() |
g.point_on_surface() |
|
polylabel(g) |
g.polylabel() |
Pole of inaccessibility. |
maximum_inscribed_circle(g) |
g.maximum_inscribed_circle() |
Returns a Circle solution: read .center and .radius from one solve, or call .to_polygon() for its contained polygonal realization. Shapely returns a center-to-boundary LineString. |
shortest_line(a, b) |
gm.shortest_line(a, b) |
Connects the closest points. Its geographic chart-edge length can exceed their geodesic distance; compare using the same unit=. |
ops.nearest_points(a, b) |
gm.nearest_points(a, b) |
The (pa, pb) pair behind shortest_line. |
delaunay_triangles(g) |
g.triangulate(method='delaunay') |
Use method='constrained' for constrained edges or method='earcut' for polygon interiors. |
| Voronoi diagram output | g.voronoi() / g.voronoi(output='edges') |
Use the output keyword to select cells or internal edges. |
shapely.ops.polygonize(...) / shapely.ops.polygonize_full(...) |
gm.polygonize_all(values), with diagnostics=True for pooled cut edges, dangles, and invalid rings; array.polygonize() for independent rows |
The pooled function accepts a GeometryArray directly and pools its present rows; see geographic diagnostic semantics. |
build_area(...) (GEOS) |
(...).build_area() |
Even-odd fill; unlike polygonize. |
node(...) (GEOS 3.7+) |
(...).node() |
Noded linework as MultiLineString. |
line_merge(...) |
(...).line_merge() |
|
shared_paths(...) |
gm.shared_paths(...) |
|
snap(g, ref, tol) |
gm.snap(g, ref, tol) |
GEOS's vertex pass moves at most one source vertex per reference vertex and requires distance < tol; gometry independently snaps every source vertex at distance <= tol to its nearest reference (ties by smallest X, then Y) and collapses consecutive equal-X/Y line coordinates. |
segmentize(g, max_len) |
g.segmentize(max_len) |
|
remove_repeated_points(...) |
(...).remove_repeated_points() |
|
minimum_rotated_rectangle(g) |
g.minimum_rotated_rectangle() |
|
geom.reverse() / shapely.reverse(geom) |
geom.reverse() |
|
orient(g) |
g.orient_polygons() |
|
normalize(g) |
g.normalize() |
|
affine (affinity.*) |
geom.translate(...) / rotate(...) / scale(...) / skew(...) / affine_transform(...) |
Linear referencing¶
| Shapely | gometry | Notes |
|---|---|---|
line.interpolate(d) |
line.line_interpolate(d) |
|
line.project(pt) |
line.line_locate(pt) |
|
substring(line, a, b) |
line.line_substring(a, b) |
|
split(geom, splitter) |
gm.split(geom, splitter) |
Binary free function; array line inputs return one Groups row per source line. |
Validation, repair, precision¶
| Shapely | gometry | Notes |
|---|---|---|
geom.is_valid |
geom.is_valid |
Unchanged; geom.validate() adds the reason/location. |
explain_validity(geom) |
report.reason / report.location |
|
make_valid(geom) |
geom.repair() |
|
set_precision(g, grid_size) |
geom.snap_to_grid(grid_size=..., repair=...) |
Closest fixed-grid snap. grid_size must be positive and finite; unlike coverage_clean(grid_size=0), zero is invalid. Optional repair=. JTS-style snap-rounding precision models are not supported. |
| — | geom.quantize(precision) |
Decimal-place rounding of coordinates (different model from set_precision). |
require(...) at boundary |
gm.require(obj, crs=..., axes=...) |
Storage contract. |
geom.is_empty / is_ring / is_simple / is_closed |
geom.is_empty / geom.is_ring / geom.is_simple / geom.is_closed |
|
is_ccw(ring) |
g.is_ccw / geom.is_ccw |
Closed LineString winding. |
force_2d(g) / force_3d(g, z) |
g.force_2d() / g.force_3d(z) |
force_3d fills only missing Z. Replace values everywhere with g.with_coordinates(z=z, m=m); None clears an axis. |
IO¶
| Shapely | gometry |
|---|---|
WKB from_wkb(b) / to_wkb(g) |
gm.from_wkb(b) / g.to_wkb(include_srid=...) |
| EWKB | gm.from_wkb(b) / g.to_wkb(include_srid=True) |
WKT from_wkt(s) / to_wkt(g) |
gm.from_wkt(s) / g.to_wkt() |
| GeoJSON | gm.from_geojson(obj) / g.to_geojson() |
| GeoJSON features w/ attributes | gm.from_geojson(fc, features=True) → validated Features record; serialize it with Features.__geo_interface__, or use gm.to_feature_collection(geoms, properties=..., ids=...) for separate columns |
geom.__geo_interface__ |
geom.__geo_interface__ |
| GeoArrow | gm.from_arrow(obj) / geom.to_arrow() |
shapely.to_wkb(Point(...)) / shapely.to_wkb(box(...)) |
gm.Point(x, y).to_wkb(precision=...) / gm.box(...).to_wkb(include_srid=..., precision=...) |
shapely.to_wkt(Point(...)) / shapely.to_wkt(box(...)) |
gm.Point(x, y).to_wkt(precision=...) / gm.box(...).to_wkt(precision=...) |
Shapely's to_wkt(output_dimension=2) becomes geom.force_2d().to_wkt() in
gometry. Remove geometry axes before writing with force_2d(),
with_coordinates(z=None), or with_coordinates(m=None); use coords.select(...) to choose a coordinate-view layout
for coordinate exports without changing the geometry.
Indexing & prepared¶
| Shapely | gometry | Notes |
|---|---|---|
STRtree(geoms) |
gm.SpatialIndex(geoms) |
|
tree.query(g) |
idx.candidates(g) |
|
tree.query(g, predicate=...) |
idx.query(g, predicate=...) |
|
tree.nearest(g) |
idx.nearest(g, unit=...) |
|
tree.query_nearest(g, exclusive=True) |
idx.nearest(g, exclusive=True) |
skip self-matches |
prepare(g) + predicate |
gm.<predicate>(g, geom) or idx.query(g, predicate=...) |
A geometry indexes itself once it is probed repeatedly. |
pyproj¶
| pyproj | gometry | Notes |
|---|---|---|
CRS.from_epsg(4326) |
gm.CRS(4326) |
CRS object; geom.crs returns one. |
gdf.set_crs(c) |
geom.with_crs(c) |
|
gdf.to_crs(c) |
geom.to_crs(c) |
|
Transformer.from_crs(a, b) + .transform(x, y) |
gm.crs_transform(a, b, x, y, z=..., t=...) |
|
transformer.transform_bounds(...) |
gm.crs_transform_bounds(...) |
|
always_xy=True |
gometry X/Y coordinates | |
query_utm_crs_info(...) |
geom.estimate_local_crs() / geoms.estimate_local_crs() |
Scalar and array receiver methods → CRS. |
| polar/UPS selection | geom.estimate_local_crs() |
|
crs.is_geographic / is_projected |
gm.CRS(c).is_geographic / .is_projected |
is_* property family. |
crs.axis_info |
gm.CRS(c).axis_order |
Diagnostic only; boundary stays X/Y. |
crs.to_authority() / to_epsg() |
gm.CRS(c).to_authority() / .to_epsg() |
|
crs.to_wkt() / to_proj4() / to_json() |
gm.CRS(c).to_wkt() / .to_proj() / .to_projjson(); pass as_dict=True for a mapping |
|
crs == other |
gm.CRS(c) == gm.CRS(other) |
Structural equality compares stored definitions; use same_as for operational equivalence. |
CRS.from_user_input(...) normalize |
gm.CRS(c).definition / gm.CRS(c).identify() |
definition retains normalized authored text; identify() supplies authority metadata. |
crs.to_2d() / to_3d() |
gm.CRS(c).to_2d() / .to_3d() |
Return a CRS. |
| unit / factors | gm.crs_unit(c) / gm.crs_units(c) / gm.CRS(c).factors(lon, lat) |
|
| database / search | gm.crs_authorities() / gm.crs_codes(...) / gm.crs_catalog(name=...) |
Module-level crs_* functions. |
| catalogs | gm.crs_ellipsoids() / gm.crs_prime_meridians() / gm.crs_proj_operations() / gm.crs_utm_zones(...) / gm.crs_celestial_bodies() |
|
| operations | gm.CRS(a).operation(b) / .operations(b) / .operation(b, at=(x, y)) / gm.crs_apply(...) |
|
| grid lookup | gm.crs_grid(...) |
Local grid metadata and availability. |
Geodesy (Geod)¶
pyproj Geod |
gometry (geometry on a geographic CRS) | Notes |
|---|---|---|
g.inv(...) distance |
gm.distance(a, b) |
|
g.inv(...) azimuth |
gm.bearing(a, b) |
|
g.inv(...) back azimuth |
gm.bearing(b, a) |
|
g.fwd(lon, lat, az, d) |
point.destination(bearing, distance) |
|
g.line_length(...) |
line.length |
|
g.geometry_area_perimeter(...) |
poly.area / poly.length |
|
g.npts(...) |
gm.point_between(a, b, 0.5, normalized=True) |
|
| geographic meter buffer | point.buffer(meters) on a geographic CRS (local-projection approximation) |
|
| non-WGS 84 ellipsoid | The same calls on points in that geographic CRS, e.g. gm.Point(lon, lat, crs=4230); geom.area / geom.length likewise |
h3-py¶
| h3-py | gometry | Notes |
|---|---|---|
latlng_to_cell(lat, lng, r) |
gm.H3Cell(point, resolution=r) |
|
cell_to_boundary(h) |
cell.polygon / cells.polygon |
|
polygon_to_cells(poly, r) / polyfill |
gm.h3_cover(geom, resolution=r, cell_rule="center") |
|
compact_cells / uncompact_cells |
cells.compact() / cells.uncompact(r) |
|
| per-point membership | gm.covers(geom, points) |
s2sphere¶
| s2sphere | gometry | Notes |
|---|---|---|
CellId.from_lat_lng(...).parent(level) |
gm.S2Cell(point, level=...) |
|
Cell(cell_id) boundary |
cell.polygon / cells.polygon |
|
RegionCoverer().get_covering(region) |
gm.s2_cover(geom, ...) |
target_cells guides refinement; max_cells is the hard output cap. |
RegionCoverer(min_level=L, max_level=L).get_covering(region) |
gm.s2_cover(geom, level=L, max_cells=...) |
The requested level is never coarsened. |
CellUnion set ops |
gm.s2_union(a, b) / gm.s2_intersection(a, b) / gm.s2_difference(a, b) |
|
CellUnion.normalize() / expand |
cells.compact() / cells.uncompact(level) |
|
| geometry membership | gm.covers(geometry, probe) |
rtree / STRtree / GeoPandas¶
| Old | gometry | Notes |
|---|---|---|
rtree.index.Index() + insert(id, bbox) |
gm.SpatialIndex(geoms) |
Geometry-aware, bulk-loaded. |
list(idx.intersection(bbox)) |
idx.candidates(geom) |
|
| candidates + manual refine | idx.query(geom, predicate=...) |
|
idx.nearest(bbox, n) |
idx.nearest(geom, k=n, unit=...) |
|
STRtree(geoms) |
gm.SpatialIndex(geoms) |
|
geopandas.sjoin(a, b, predicate=...) |
gm.join(a, b, predicate=...) |
python-geohash / pygeohash¶
| Old | gometry | Notes |
|---|---|---|
geohash.encode(lat, lon, precision=p) |
gm.GeohashCell(lon, lat, precision=p).token |
|
geohash.decode(token) |
cell.center |
|
geohash.bbox(token) |
cell.polygon.bounds |
|
geohash.neighbors(token) |
cell.neighbors |
8-neighborhood, seam-wrapping. |
| coverage of a polygon | gm.geohash_cover(geom, precision=p) |
mercantile¶
| mercantile | gometry | Notes |
|---|---|---|
mercantile.tile(lng, lat, zoom) |
gm.Tile(lon=lng, lat=lat, zoom=z) |
Typed Tile with .zoom/.x/.y. |
mercantile.quadkey(tile) |
tile.token |
|
mercantile.quadkey_to_tile(qk) |
gm.Tile(qk) |
|
mercantile.bounds(tile) |
tile.polygon.bounds |
Tile footprint bounds. |
mercantile.parent/children(tile) |
tile.parent() / tile.children() |
|
mercantile.tiles(*bbox, zooms) |
gm.tile_cover(geom, zoom=z) |
polyline / openlocationcode / OSM shortlink¶
| Old | gometry | Notes |
|---|---|---|
polyline.decode(s) |
gm.from_polyline(s) |
Returns a Point for one coordinate, otherwise a LineString (or array). |
polyline.encode(coords) |
line.to_polyline() / geom.to_polyline() |
|
openlocationcode.encode(lat, lng) |
gm.pluscode_encode(lng, lat) |
|
openlocationcode.decode(code) |
gm.pluscode_polygon(code) |
Returns the cell Polygon. |
shorten / recoverNearest |
gm.pluscode_shorten / gm.pluscode_recover |
|
OSM ShortLink.encode/decode |
gm.osm_shortlink_encode / gm.osm_shortlink_location |
Legacy @ accepted. |
scikit-learn / scipy clustering¶
| Old | gometry | Notes |
|---|---|---|
DBSCAN(...).fit(coords) / k-means / hierarchical clustering |
feed np.asarray(geom.coords, dtype=np.float64) (or .coords.x/.y) to scikit-learn / scipy |
gometry stays a geometry engine; cluster in coordinate space via NumPy handoff. |
| scattered-data interpolation (IDW, kriging, …) | scipy / scikit-gstat over np.asarray(geom.coords, dtype=np.float64) |
Project to a suitable CRS first when planar XY is wrong. |