Shapely#
Manipulation and analysis of geometric objects in the Cartesian plane.
Shapely is a BSD-licensed Python package for manipulation and analysis of planar geometric objects. It is using the widely deployed open-source geometry library GEOS (the engine of PostGIS, and a port of JTS). Shapely wraps GEOS geometries and operations to provide both a feature rich Geometry interface for singular (scalar) geometries and higher-performance NumPy ufuncs for operations using arrays of geometries. Shapely is not primarily focused on data serialization formats or coordinate systems, but can be readily integrated with packages that are.
What is a ufunc?#
A universal function (or ufunc for short) is a function that operates on
n-dimensional arrays on an element-by-element fashion and supports array
broadcasting. The underlying for
loops are implemented in C to reduce the
overhead of the Python interpreter.
Multithreading#
Shapely functions generally support multithreading by releasing the Global Interpreter Lock (GIL) during execution. Normally in Python, the GIL prevents multiple threads from computing at the same time. Shapely functions internally release this constraint so that the heavy lifting done by GEOS can be done in parallel, from a single Python process.
Usage#
Here is the canonical example of building an approximately circular patch by buffering a point, using the scalar Geometry interface:
>>> from shapely import Point
>>> patch = Point(0.0, 0.0).buffer(10.0)
>>> patch
<POLYGON ((10 0, 9.952 -0.98, 9.808 -1.951, 9.569 -2.903, 9.239 -3.827, 8.81...>
>>> patch.area
313.6548490545941
Using the vectorized ufunc interface (instead of using a manual for loop), compare an array of points with a polygon:
>>> import shapely
>>> import numpy as np
>>> geoms = np.array([Point(0, 0), Point(1, 1), Point(2, 2)])
>>> polygon = shapely.box(0, 0, 2, 2)
>>> shapely.contains(polygon, geoms)
array([False, True, False])
See the documentation for more examples and guidance: https://shapely.readthedocs.io
Requirements#
Shapely 2.0 requires
Python >=3.7
GEOS >=3.5
NumPy >=1.14
Installing Shapely#
We recommend installing Shapely using one of the available built
distributions, for example using pip
or conda
:
$ pip install shapely
# or using conda
$ conda install shapely --channel conda-forge
See the installation documentation for more details and advanced installation instructions.
Integration#
Shapely does not read or write data files, but it can serialize and deserialize using several well known formats and protocols. The shapely.wkb and shapely.wkt modules provide dumpers and loaders inspired by Python’s pickle module.
>>> from shapely.wkt import dumps, loads
>>> dumps(loads('POINT (0 0)'))
'POINT (0.0000000000000000 0.0000000000000000)'
Shapely can also integrate with other Python GIS packages using GeoJSON-like dicts.
>>> import json
>>> from shapely.geometry import mapping, shape
>>> s = shape(json.loads('{"type": "Point", "coordinates": [0.0, 0.0]}'))
>>> s
<POINT (0 0)>
>>> print(json.dumps(mapping(s)))
{"type": "Point", "coordinates": [0.0, 0.0]}
Support#
Questions about using Shapely may be asked on the GIS StackExchange using the “shapely” tag.
Bugs may be reported at shapely/shapely#issues.
Copyright & License#
Shapely is licensed under BSD 3-Clause license. GEOS is available under the terms of GNU Lesser General Public License (LGPL) 2.1 at https://libgeos.org.
Credits#
Shapely is written by:
Adi Shavit <adishavit@gmail.com>
Alan D. Snow <alansnow21@gmail.com>
Alberto Rubiales <arubiales11@gmail.com>
Allan Adair <allan.m.adair@gmail.com>
Andrew Blakey <ablakey@gmail.com>
Andy Freeland <andy@andyfreeland.net>
Ariel Kadouri <ariel@arielsartistry.com>
Aron Bierbaum <aronbierbaum@gmail.com>
Bart Broere <2715782+bartbroere@users.noreply.github.com>
Bas Couwenberg <sebastic@xs4all.nl>
Ben Beasley <code@musicinmybrain.net>
Benjamin Root <ben.v.root@gmail.com>
BertrandGervais <bertrand.gervais.pro@gmail.com>
Bhavika Tekwani <4955119+bhavika@users.noreply.github.com>
Bi0T1N <Bi0T1N@users.noreply.github.com>
Brad Hards <bradh@frogmouth.net>
Brendan Ward <bcward@astutespruce.com>
Brandon Wood <btwood@geometeor.com>
Casper van der Wel <caspervdw@gmail.com>
Chad Hawkins <cwh@chadwhawkins.com>
Christian Prior <cprior@gmail.com>
Christian Quest <github@cquest.org>
Christophe Pradal <christophe.pradal@inria.fr>
Dan Baston <dbaston@gmail.com>
Dan Mahr <danmahr23@gmail.com>
Daniele Esposti <expobrain@users.noreply.github.com>
Dave Collins <dave@hopest.net>
David Baumgold <david@davidbaumgold.com>
David Swinkels <davidswinkelss@gmail.com>
Denis Rykov <rykovd@gmail.com>
Enrico Ferreguti <enricofer@gmail.com>
Erwin Sterrenburg <e.w.sterrenburg@gmail.com>
Ewout ter Hoeven <E.M.terHoeven@student.tudelft.nl>
Felix Divo <4403130+felixdivo@users.noreply.github.com>
Felix Yan <felixonmars@archlinux.org>
Filipe Fernandes <ocefpaf@gmail.com>
Frédéric Junod <frederic.junod@camptocamp.com>
Gabi Davar <grizzly.nyo@gmail.com>
Gerrit Holl <gerrit.holl@dwd.de>
Hannes <kannes@users.noreply.github.com>
Hao Zheng <Furioushaozheng@gmail.com>
Henry Walshaw <henry.walshaw@gmail.com>
Howard Butler <hobu.inc@gmail.com>
Idan Miara <idan@miara.com>
Jacob Wasserman <jwasserman@gmail.com>
Jaeha Lee <jaehaaheaj@gmail.com>
James Douglass <jamesdouglassusa@gmail.com>
James Gaboardi <jgaboardi@gmail.com>
James Lamb <jaylamb20@gmail.com>
James McBride <jdmcbr@gmail.com>
James Spencer <james.s.spencer@gmail.com>
Jamie Hall <jamie1212@gmail.com>
Jason Sanford <jason.sanford@mapmyfitness.com>
Jeethu Rao <jeethu@jeethurao.com>
Jeremiah England <34973839+Jeremiah-England@users.noreply.github.com>
Jinkun Wang <mejkunw@gmail.com>
Johan Euphrosine <proppy@aminche.com>
Johannes Schönberger <jschoenberger@demuc.de>
Jonathan Schoonhoven <jschoonhoven@lyft.com>
Joris Van den Bossche <jorisvandenbossche@gmail.com>
Joshua Arnott <josh@snorfalorpagus.net>
Juan Luis Cano Rodríguez <juanlu@satellogic.com>
Justin Shenk <shenk.justin@gmail.com>
Kai Lautaportti <dokai@b426a367-1105-0410-b9ff-cdf4ab011145>
Kelsey Jordahl <kjordahl@enthought.com>
Kevin Wurster <wursterk@gmail.com>
Konstantin Veretennicov <kveretennicov@gmail.com>
Koshy Thomas <koshy1123@gmail.com>
Krishna Chaitanya <bkchaitan94@gmail.com>
Kristian Evers <kristianevers@gmail.com>
Kyle Barron <kylebarron2@gmail.com>
Leandro Lima <leandro@limaesilva.com.br>
Lukasz <uhho@users.noreply.github.com>
Luke Lee <durdenmisc@gmail.com>
Maarten Vermeyen <maarten.vermeyen@rwo.vlaanderen.be>
Marc Jansen <jansen@terrestris.de>
Marco De Nadai <me@marcodena.it>
Martin Fleischmann <martin@martinfleischmann.net>
Mathieu <mathieu.nivel@gmail.com>
Matt Amos <matt.amos@mapzen.com>
Matthias Cuntz <mcuntz@users.noreply.github.com>
MejstrikRudolf <68251685+MejstrikRudolf@users.noreply.github.com>
Michael K <michael-k@users.noreply.github.com>
Michel Blancard <michel.blancard@data.gouv.fr>
Mike Taves <mwtoews@gmail.com>
Morris Tweed <tweed.morris@gmail.com>
Naveen Michaud-Agrawal <naveen.michaudagrawal@gmail.com>
Oliver Tonnhofer <olt@bogosoft.com>
Paveł Tyślacki <tbicr@users.noreply.github.com>
Peter Sagerson <psagers.github@ignorare.net>
Phil Elson <pelson.pub@gmail.com>
Pierre PACI <villerupt@gmail.com>
Raja Gangopadhya <raja.gangopadhya@ridewithvia.com>
Ricardo Zilleruelo <51384295+zetaatlyft@users.noreply.github.com>
Rémy Phelipot <remy-phelipot@users.noreply.github.com>
S Murthy <sr-murthy@users.noreply.github.com>
Sampo Syrjanen <sampo.syrjanen@here.com>
Samuel Chin <samuelchin91@gmail.com>
Sean Gillies <sean.gillies@gmail.com>
Sobolev Nikita <mail@sobolevn.me>
Stephan Hügel <urschrei@gmail.com>
Steve M. Kim <steve@climate.com>
Taro Matsuzawa aka. btm <btm@tech.email.ne.jp>
Thibault Deutsch <thibault.deutsch@gmail.com>
Thomas Gratier <thomas_gratier@yahoo.fr>
Thomas Kluyver <takowl@gmail.com>
Tim Gates <tim.gates@iress.com>
Tobias Sauerwein <tobias.sauerwein@camptocamp.com>
Tom Caruso <carusot42@gmail.com>
Tom Clancy <17627475+clncy@users.noreply.github.com>
WANG Aiyong <gepcelway@gmail.com>
Will May <williamcmay@live.com>
Zachary Ware <zachary.ware@gmail.com>
aharfoot <aharfoot@users.noreply.github.com>
bstadlbauer <11799671+bstadlbauer@users.noreply.github.com>
cclauss <cclauss@me.com>
davidh-ssec <david.hoese@ssec.wisc.edu>
georgeouzou <geothrock@gmail.com>
giumas <gmasetti@ccom.unh.edu>
gpapadok <38889721+gpapadok@users.noreply.github.com>
joelostblom <joelostblom@users.noreply.github.com>
ljwolf <levi.john.wolf@gmail.com>
mindw <grizzly.nyo@gmail.com>
shongololo <garethsimons@me.com>
solarjoe <walterwhite666@googlemail.com>
sshuair <sshuair@gmail.com>
stephenworsley <49274989+stephenworsley@users.noreply.github.com>
See also: shapely/shapely.
Additional help from:
Justin Bronn (GeoDjango) for ctypes inspiration
Martin Davis (JTS)
Sandro Santilli, Mateusz Loskot, Paul Ramsey, et al (GEOS Project)
Major portions of this work were supported by a grant (for Pleiades) from the U.S. National Endowment for the Humanities (https://www.neh.gov).
Frequently asked questions and answers#
I installed shapely in a conda environment using pip. Why doesn’t it work?#
Shapely versions < 2.0 load a GEOS shared library using ctypes. It’s not uncommon for users to have multiple copies of GEOS libs on their system. Loading the correct one is complicated and shapely has a number of platform-dependent GEOS library loading bugs. The project has particularly poor support for finding the correct GEOS library for a shapely package installed from PyPI into a conda environment. We recommend that conda users always get shapely from conda-forge.
Are there references for the algorithms used by shapely?#
Generally speaking, shapely’s predicates and operations are derived from methods of the same name from GEOS and the JTS Topology Suite. See the JTS FAQ for references describing the JTS algorithms.
I used .buffer() on a geometry with Z coordinates. Where did the Z coordinates go?#
The buffer algorithm in GEOS is purely two-dimensional and discards any Z coordinates. This is generally the case for the GEOS algorithms.