creation.py 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. """Methods to create geometries."""
  2. import numpy as np
  3. from shapely import Geometry, GeometryType, lib
  4. from shapely._enum import ParamEnum
  5. from shapely._geometry_helpers import collections_1d, simple_geometries_1d
  6. from shapely.decorators import deprecate_positional, multithreading_enabled
  7. from shapely.io import from_wkt
  8. __all__ = [
  9. "box",
  10. "destroy_prepared",
  11. "empty",
  12. "geometrycollections",
  13. "linearrings",
  14. "linestrings",
  15. "multilinestrings",
  16. "multipoints",
  17. "multipolygons",
  18. "points",
  19. "polygons",
  20. "prepare",
  21. ]
  22. class HandleNaN(ParamEnum):
  23. allow = 0
  24. skip = 1
  25. error = 2
  26. def _xyz_to_coords(x, y, z):
  27. if y is None:
  28. return x
  29. if z is None:
  30. coords = np.broadcast_arrays(x, y)
  31. else:
  32. coords = np.broadcast_arrays(x, y, z)
  33. return np.stack(coords, axis=-1)
  34. # Note: future plan is to change this signature over a few releases:
  35. # shapely 2.0:
  36. # points(coords, y=None, z=None, indices=None, out=None, **kwargs)
  37. # shapely 2.1: shows deprecation warning about positional 'indices' arg
  38. # points(coords, y=None, z=None, indices=None, *, handle_nan=HandleNaN.allow, out=None, **kwargs) # noqa: E501
  39. # shapely 2.2(?): enforce keyword-only arguments after 'z'
  40. # points(coords, y=None, z=None, *, indices=None, handle_nan=HandleNaN.allow, out=None, **kwargs) # noqa: E501
  41. @deprecate_positional(["indices"], category=DeprecationWarning)
  42. @multithreading_enabled
  43. def points(
  44. coords,
  45. y=None,
  46. z=None,
  47. indices=None,
  48. *,
  49. handle_nan=HandleNaN.allow,
  50. out=None,
  51. **kwargs,
  52. ):
  53. """Create an array of points.
  54. Parameters
  55. ----------
  56. coords : array_like
  57. An array of coordinate tuples (2- or 3-dimensional) or, if ``y`` is
  58. provided, an array of x coordinates.
  59. y : array_like, optional
  60. An array of y coordinates.
  61. z : array_like, optional
  62. An array of z coordinates.
  63. indices : array_like, optional
  64. Indices into the target array where input coordinates belong. If
  65. provided, the coords should be 2D with shape (N, 2) or (N, 3) and
  66. indices should be an array of shape (N,) with integers in increasing
  67. order. Missing indices result in a ValueError unless ``out`` is
  68. provided, in which case the original value in ``out`` is kept.
  69. handle_nan : shapely.HandleNaN or {'allow', 'skip', 'error'}, default 'allow'
  70. Specifies what to do when a NaN or Inf is encountered in the coordinates:
  71. - 'allow': the geometries are created with NaN or Inf coordinates.
  72. Note that this can result in unexpected behaviour in subsequent
  73. operations, and generally it is discouraged to have non-finite
  74. coordinate values. One can use this option if you know all
  75. coordinates are finite and want to avoid the overhead of checking
  76. for this.
  77. - 'skip': if any of x, y or z values are NaN or Inf, an empty point
  78. will be created.
  79. - 'error': if any NaN or Inf is detected in the coordinates, a ValueError
  80. is raised. This option ensures that the created geometries have all
  81. finite coordinate values.
  82. .. versionadded:: 2.1.0
  83. out : ndarray, optional
  84. An array (with dtype object) to output the geometries into.
  85. **kwargs
  86. See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
  87. Ignored if ``indices`` is provided.
  88. Examples
  89. --------
  90. >>> import shapely
  91. >>> shapely.points([[0, 1], [4, 5]]).tolist()
  92. [<POINT (0 1)>, <POINT (4 5)>]
  93. >>> shapely.points([0, 1, 2])
  94. <POINT Z (0 1 2)>
  95. Notes
  96. -----
  97. - GEOS 3.10, 3.11 and 3.12 automatically converts POINT (nan nan) to POINT EMPTY.
  98. - GEOS 3.10 and 3.11 will transform a 3D point to 2D if its Z coordinate is NaN.
  99. - Usage of the ``y`` and ``z`` arguments will prevents lazy evaluation in
  100. ``dask``. Instead provide the coordinates as an array with shape
  101. ``(..., 2)`` or ``(..., 3)`` using only the ``coords`` argument.
  102. """
  103. coords = _xyz_to_coords(coords, y, z)
  104. if isinstance(handle_nan, str):
  105. handle_nan = HandleNaN.get_value(handle_nan)
  106. if indices is None:
  107. return lib.points(coords, np.intc(handle_nan), out=out, **kwargs)
  108. else:
  109. return simple_geometries_1d(
  110. coords, indices, GeometryType.POINT, handle_nan=handle_nan, out=out
  111. )
  112. # Note: future plan is to change this signature over a few releases:
  113. # shapely 2.0:
  114. # linestrings(coords, y=None, z=None, indices=None, out=None, **kwargs)
  115. # shapely 2.1: shows deprecation warning about positional 'indices' arg
  116. # linestrings(coords, y=None, z=None, indices=None, *, handle_nan=HandleNaN.allow, out=None, **kwargs) # noqa: E501
  117. # shapely 2.2(?): enforce keyword-only arguments after 'z'
  118. # linestrings(coords, y=None, z=None, *, indices=None, handle_nan=HandleNaN.allow, out=None, **kwargs) # noqa: E501
  119. @deprecate_positional(["indices"], category=DeprecationWarning)
  120. @multithreading_enabled
  121. def linestrings(
  122. coords,
  123. y=None,
  124. z=None,
  125. indices=None,
  126. *,
  127. handle_nan=HandleNaN.allow,
  128. out=None,
  129. **kwargs,
  130. ):
  131. """Create an array of linestrings.
  132. This function will raise an exception if a linestring contains less than
  133. two points.
  134. Parameters
  135. ----------
  136. coords : array_like
  137. An array of lists of coordinate tuples (2- or 3-dimensional) or, if ``y``
  138. is provided, an array of lists of x coordinates.
  139. y : array_like, optional
  140. An array of y coordinates.
  141. z : array_like, optional
  142. An array of z coordinates.
  143. indices : array_like, optional
  144. Indices into the target array where input coordinates belong. If
  145. provided, the coords should be 2D with shape (N, 2) or (N, 3) and
  146. indices should be an array of shape (N,) with integers in increasing
  147. order. Missing indices result in a ValueError unless ``out`` is
  148. provided, in which case the original value in ``out`` is kept.
  149. handle_nan : shapely.HandleNaN or {'allow', 'skip', 'error'}, default 'allow'
  150. Specifies what to do when a NaN or Inf is encountered in the coordinates:
  151. - 'allow': the geometries are created with NaN or Inf coordinates.
  152. Note that this can result in unexpected behaviour in subsequent
  153. operations, and generally it is discouraged to have non-finite
  154. coordinate values. One can use this option if you know all
  155. coordinates are finite and want to avoid the overhead of checking
  156. for this.
  157. - 'skip': the coordinate pairs where any of x, y or z values are
  158. NaN or Inf are ignored. If this results in ignoring all coordinates
  159. for one geometry, an empty geometry is created.
  160. - 'error': if any NaN or Inf is detected in the coordinates, a ValueError
  161. is raised. This option ensures that the created geometries have all
  162. finite coordinate values.
  163. .. versionadded:: 2.1.0
  164. out : ndarray, optional
  165. An array (with dtype object) to output the geometries into.
  166. **kwargs
  167. See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
  168. Ignored if ``indices`` is provided.
  169. Examples
  170. --------
  171. >>> import shapely
  172. >>> shapely.linestrings([[[0, 1], [4, 5]], [[2, 3], [5, 6]]]).tolist()
  173. [<LINESTRING (0 1, 4 5)>, <LINESTRING (2 3, 5 6)>]
  174. >>> shapely.linestrings(
  175. ... [[0, 1], [4, 5], [2, 3], [5, 6], [7, 8]],
  176. ... indices=[0, 0, 1, 1, 1]
  177. ... ).tolist()
  178. [<LINESTRING (0 1, 4 5)>, <LINESTRING (2 3, 5 6, 7 8)>]
  179. Notes
  180. -----
  181. - Usage of the ``y`` and ``z`` arguments will prevents lazy evaluation in
  182. ``dask``. Instead provide the coordinates as a ``(..., 2)`` or
  183. ``(..., 3)`` array using only ``coords``.
  184. """
  185. coords = _xyz_to_coords(coords, y, z)
  186. if isinstance(handle_nan, str):
  187. handle_nan = HandleNaN.get_value(handle_nan)
  188. if indices is None:
  189. return lib.linestrings(coords, np.intc(handle_nan), out=out, **kwargs)
  190. else:
  191. return simple_geometries_1d(
  192. coords, indices, GeometryType.LINESTRING, handle_nan=handle_nan, out=out
  193. )
  194. # Note: future plan is to change this signature over a few releases:
  195. # shapely 2.0:
  196. # linearrings(coords, y=None, z=None, indices=None, out=None, **kwargs)
  197. # shapely 2.1: shows deprecation warning about positional 'indices' arg
  198. # linearrings(coords, y=None, z=None, indices=None, *, handle_nan=HandleNaN.allow, out=None, **kwargs) # noqa: E501
  199. # shapely 2.2(?): enforce keyword-only arguments after 'z'
  200. # linearrings(coords, y=None, z=None, *, indices=None, handle_nan=HandleNaN.allow, out=None, **kwargs) # noqa: E501
  201. @deprecate_positional(["indices"], category=DeprecationWarning)
  202. @multithreading_enabled
  203. def linearrings(
  204. coords,
  205. y=None,
  206. z=None,
  207. indices=None,
  208. *,
  209. handle_nan=HandleNaN.allow,
  210. out=None,
  211. **kwargs,
  212. ):
  213. """Create an array of linearrings.
  214. If the provided coords do not constitute a closed linestring, or if there
  215. are only 3 provided coords, the first
  216. coordinate is duplicated at the end to close the ring. This function will
  217. raise an exception if a linearring contains less than three points or if
  218. the terminal coordinates contain NaN (not-a-number).
  219. Parameters
  220. ----------
  221. coords : array_like
  222. An array of lists of coordinate tuples (2- or 3-dimensional) or, if ``y``
  223. is provided, an array of lists of x coordinates
  224. y : array_like, optional
  225. An array of y coordinates.
  226. z : array_like, optional
  227. An array of z coordinates.
  228. indices : array_like, optional
  229. Indices into the target array where input coordinates belong. If
  230. provided, the coords should be 2D with shape (N, 2) or (N, 3) and
  231. indices should be an array of shape (N,) with integers in increasing
  232. order. Missing indices result in a ValueError unless ``out`` is
  233. provided, in which case the original value in ``out`` is kept.
  234. handle_nan : shapely.HandleNaN or {'allow', 'skip', 'error'}, default 'allow'
  235. Specifies what to do when a NaN or Inf is encountered in the coordinates:
  236. - 'allow': the geometries are created with NaN or Inf coordinates.
  237. Note that this can result in unexpected behaviour in subsequent
  238. operations, and generally it is discouraged to have non-finite
  239. coordinate values. One can use this option if you know all
  240. coordinates are finite and want to avoid the overhead of checking
  241. for this.
  242. - 'skip': the coordinate pairs where any of x, y or z values are
  243. NaN or Inf are ignored. If this results in ignoring all coordinates
  244. for one geometry, an empty geometry is created.
  245. - 'error': if any NaN or Inf is detected in the coordinates, a ValueError
  246. is raised. This option ensures that the created geometries have all
  247. finite coordinate values.
  248. .. versionadded:: 2.1.0
  249. out : ndarray, optional
  250. An array (with dtype object) to output the geometries into.
  251. **kwargs
  252. See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
  253. Ignored if ``indices`` is provided.
  254. See Also
  255. --------
  256. linestrings
  257. Examples
  258. --------
  259. >>> import shapely
  260. >>> shapely.linearrings([[0, 0], [0, 1], [1, 1], [0, 0]])
  261. <LINEARRING (0 0, 0 1, 1 1, 0 0)>
  262. >>> shapely.linearrings([[0, 0], [0, 1], [1, 1]])
  263. <LINEARRING (0 0, 0 1, 1 1, 0 0)>
  264. Notes
  265. -----
  266. - Usage of the ``y`` and ``z`` arguments will prevents lazy evaluation in
  267. ``dask``. Instead provide the coordinates as a ``(..., 2)`` or
  268. ``(..., 3)`` array using only ``coords``.
  269. """
  270. coords = _xyz_to_coords(coords, y, z)
  271. if isinstance(handle_nan, str):
  272. handle_nan = HandleNaN.get_value(handle_nan)
  273. if indices is None:
  274. return lib.linearrings(coords, np.intc(handle_nan), out=out, **kwargs)
  275. else:
  276. return simple_geometries_1d(
  277. coords, indices, GeometryType.LINEARRING, handle_nan=handle_nan, out=out
  278. )
  279. # Note: future plan is to change this signature over a few releases:
  280. # shapely 2.0:
  281. # polygons(geometries, holes=None, indices=None, out=None, **kwargs)
  282. # shapely 2.1: shows deprecation warning about positional 'indices' arg
  283. # polygons(geometries, holes=None, indices=None, *, out=None, **kwargs)
  284. # shapely 2.2(?): enforce keyword-only arguments after 'holes'
  285. # polygons(geometries, holes=None, *, indices=None, out=None, **kwargs)
  286. @deprecate_positional(["indices"], category=DeprecationWarning)
  287. @multithreading_enabled
  288. def polygons(geometries, holes=None, indices=None, *, out=None, **kwargs):
  289. """Create an array of polygons.
  290. Parameters
  291. ----------
  292. geometries : array_like
  293. An array of linearrings or coordinates (see linearrings).
  294. Unless ``indices`` are given (see description below), this
  295. include the outer shells only. The ``holes`` argument should be used
  296. to create polygons with holes.
  297. holes : array_like, optional
  298. An array of lists of linearrings that constitute holes for each shell.
  299. Not to be used in combination with ``indices``.
  300. indices : array_like, optional
  301. Indices into the target array where input geometries belong. If
  302. provided, the holes are expected to be present inside ``geometries``;
  303. the first geometry for each index is the outer shell
  304. and all subsequent geometries in that index are the holes.
  305. Both geometries and indices should be 1D and have matching sizes.
  306. Indices should be in increasing order. Missing indices result in a
  307. ValueError unless ``out`` is provided, in which case the original value
  308. in ``out`` is kept.
  309. out : ndarray, optional
  310. An array (with dtype object) to output the geometries into.
  311. **kwargs
  312. See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
  313. Ignored if ``indices`` is provided.
  314. Notes
  315. -----
  316. .. deprecated:: 2.1.0
  317. A deprecation warning is shown if ``indices`` is specified as a
  318. positional argument. This will need to be specified as a keyword
  319. argument in a future release.
  320. Examples
  321. --------
  322. >>> import shapely
  323. Polygons are constructed from rings:
  324. >>> ring_1 = shapely.linearrings([[0, 0], [0, 10], [10, 10], [10, 0]])
  325. >>> ring_2 = shapely.linearrings([[2, 6], [2, 7], [3, 7], [3, 6]])
  326. >>> shapely.polygons([ring_1, ring_2])[0]
  327. <POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))>
  328. >>> shapely.polygons([ring_1, ring_2])[1]
  329. <POLYGON ((2 6, 2 7, 3 7, 3 6, 2 6))>
  330. Or from coordinates directly:
  331. >>> shapely.polygons([[0, 0], [0, 10], [10, 10], [10, 0]])
  332. <POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))>
  333. Adding holes can be done using the ``holes`` keyword argument:
  334. >>> shapely.polygons(ring_1, holes=[ring_2])
  335. <POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0), (2 6, 2 7, 3 7, 3 6, 2 6))>
  336. Or using the ``indices`` argument:
  337. >>> shapely.polygons([ring_1, ring_2], indices=[0, 1])[0]
  338. <POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))>
  339. >>> shapely.polygons([ring_1, ring_2], indices=[0, 1])[1]
  340. <POLYGON ((2 6, 2 7, 3 7, 3 6, 2 6))>
  341. >>> shapely.polygons([ring_1, ring_2], indices=[0, 0])[0]
  342. <POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0), (2 6, 2 7, 3 7, 3 6, 2 6))>
  343. Missing input values (``None``) are skipped and may result in an
  344. empty polygon:
  345. >>> shapely.polygons(None)
  346. <POLYGON EMPTY>
  347. >>> shapely.polygons(ring_1, holes=[None])
  348. <POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))>
  349. >>> shapely.polygons([ring_1, None], indices=[0, 0])[0]
  350. <POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))>
  351. """
  352. geometries = np.asarray(geometries)
  353. if not isinstance(geometries, Geometry) and np.issubdtype(
  354. geometries.dtype, np.number
  355. ):
  356. geometries = linearrings(geometries)
  357. if indices is not None:
  358. if holes is not None:
  359. raise TypeError("Cannot specify separate holes array when using indices.")
  360. return collections_1d(geometries, indices, GeometryType.POLYGON, out=out)
  361. if holes is None:
  362. # no holes provided: initialize an empty holes array matching shells
  363. shape = geometries.shape + (0,) if isinstance(geometries, np.ndarray) else (0,)
  364. holes = np.empty(shape, dtype=object)
  365. else:
  366. holes = np.asarray(holes)
  367. # convert holes coordinates into linearrings
  368. if np.issubdtype(holes.dtype, np.number):
  369. holes = linearrings(holes)
  370. return lib.polygons(geometries, holes, out=out, **kwargs)
  371. # Note: future plan is to change this signature over a few releases:
  372. # shapely 2.0:
  373. # box(xmin, ymin, xmax, ymax, ccw=True, **kwargs)
  374. # shapely 2.1: shows deprecation warning about positional 'ccw' arg
  375. # same signature as 2.0
  376. # shapely 2.2(?): enforce keyword-only arguments after 'ymax'
  377. # box(xmin, ymin, xmax, ymax, *, ccw=True, **kwargs)
  378. @deprecate_positional(["ccw"], category=DeprecationWarning)
  379. @multithreading_enabled
  380. def box(xmin, ymin, xmax, ymax, ccw=True, **kwargs):
  381. """Create box polygons.
  382. Parameters
  383. ----------
  384. xmin : float or array_like
  385. Float or array of minimum x coordinates.
  386. ymin : float or array_like
  387. Float or array of minimum y coordinates.
  388. xmax : float or array_like
  389. Float or array of maximum x coordinates.
  390. ymax : float or array_like
  391. Float or array of maximum y coordinates.
  392. ccw : bool, default True
  393. If True, box will be created in counterclockwise direction starting
  394. from bottom right coordinate (xmax, ymin).
  395. If False, box will be created in clockwise direction starting from
  396. bottom left coordinate (xmin, ymin).
  397. **kwargs
  398. See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
  399. Notes
  400. -----
  401. .. deprecated:: 2.1.0
  402. A deprecation warning is shown if ``ccw`` is specified as a
  403. positional argument. This will need to be specified as a keyword
  404. argument in a future release.
  405. Examples
  406. --------
  407. >>> import shapely
  408. >>> shapely.box(0, 0, 1, 1)
  409. <POLYGON ((1 0, 1 1, 0 1, 0 0, 1 0))>
  410. >>> shapely.box(0, 0, 1, 1, ccw=False)
  411. <POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))>
  412. """
  413. return lib.box(xmin, ymin, xmax, ymax, ccw, **kwargs)
  414. # Note: future plan is to change this signature over a few releases:
  415. # shapely 2.0:
  416. # multipoints(geometries, indices=None, out=None, **kwargs)
  417. # shapely 2.1: shows deprecation warning about positional 'indices' arg
  418. # multipoints(geometries, indices=None, *, out=None, **kwargs)
  419. # shapely 2.2(?): enforce keyword-only arguments after 'indices'
  420. # multipoints(geometries, *, indices=None, out=None, **kwargs)
  421. @deprecate_positional(["indices"], category=DeprecationWarning)
  422. @multithreading_enabled
  423. def multipoints(geometries, indices=None, *, out=None, **kwargs):
  424. """Create multipoints from arrays of points.
  425. Parameters
  426. ----------
  427. geometries : array_like
  428. An array of points or coordinates (see points).
  429. indices : array_like, optional
  430. Indices into the target array where input geometries belong. If
  431. provided, both geometries and indices should be 1D and have matching
  432. sizes. Indices should be in increasing order. Missing indices result
  433. in a ValueError unless ``out`` is provided, in which case the original
  434. value in ``out`` is kept.
  435. out : ndarray, optional
  436. An array (with dtype object) to output the geometries into.
  437. **kwargs
  438. See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
  439. Ignored if ``indices`` is provided.
  440. Notes
  441. -----
  442. .. deprecated:: 2.1.0
  443. A deprecation warning is shown if ``indices`` is specified as a
  444. positional argument. This will need to be specified as a keyword
  445. argument in a future release.
  446. Examples
  447. --------
  448. >>> import shapely
  449. Multipoints are constructed from points:
  450. >>> point_1 = shapely.points([1, 1])
  451. >>> point_2 = shapely.points([2, 2])
  452. >>> shapely.multipoints([point_1, point_2])
  453. <MULTIPOINT ((1 1), (2 2))>
  454. >>> shapely.multipoints([[point_1, point_2], [point_2, None]]).tolist()
  455. [<MULTIPOINT ((1 1), (2 2))>, <MULTIPOINT ((2 2))>]
  456. Or from coordinates directly:
  457. >>> shapely.multipoints([[0, 0], [2, 2], [3, 3]])
  458. <MULTIPOINT ((0 0), (2 2), (3 3))>
  459. Multiple multipoints of different sizes can be constructed efficiently using the
  460. ``indices`` keyword argument:
  461. >>> shapely.multipoints([point_1, point_2, point_2], indices=[0, 0, 1]).tolist()
  462. [<MULTIPOINT ((1 1), (2 2))>, <MULTIPOINT ((2 2))>]
  463. Missing input values (``None``) are skipped and may result in an
  464. empty multipoint:
  465. >>> shapely.multipoints([None])
  466. <MULTIPOINT EMPTY>
  467. >>> shapely.multipoints([point_1, None], indices=[0, 0]).tolist()
  468. [<MULTIPOINT ((1 1))>]
  469. >>> shapely.multipoints([point_1, None], indices=[0, 1]).tolist()
  470. [<MULTIPOINT ((1 1))>, <MULTIPOINT EMPTY>]
  471. """
  472. typ = GeometryType.MULTIPOINT
  473. geometries = np.asarray(geometries)
  474. if not isinstance(geometries, Geometry) and np.issubdtype(
  475. geometries.dtype, np.number
  476. ):
  477. geometries = points(geometries)
  478. if indices is None:
  479. return lib.create_collection(geometries, np.intc(typ), out=out, **kwargs)
  480. else:
  481. return collections_1d(geometries, indices, typ, out=out)
  482. # Note: future plan is to change this signature over a few releases:
  483. # shapely 2.0:
  484. # multilinestrings(geometries, indices=None, out=None, **kwargs)
  485. # shapely 2.1: shows deprecation warning about positional 'indices' arg
  486. # multilinestrings(geometries, indices=None, *, out=None, **kwargs)
  487. # shapely 2.2(?): enforce keyword-only arguments after 'indices'
  488. # multilinestrings(geometries, *, indices=None, out=None, **kwargs)
  489. @deprecate_positional(["indices"], category=DeprecationWarning)
  490. @multithreading_enabled
  491. def multilinestrings(geometries, indices=None, *, out=None, **kwargs):
  492. """Create multilinestrings from arrays of linestrings.
  493. Parameters
  494. ----------
  495. geometries : array_like
  496. An array of linestrings or coordinates (see linestrings).
  497. indices : array_like, optional
  498. Indices into the target array where input geometries belong. If
  499. provided, both geometries and indices should be 1D and have matching
  500. sizes. Indices should be in increasing order. Missing indices result
  501. in a ValueError unless ``out`` is provided, in which case the original
  502. value in ``out`` is kept.
  503. out : ndarray, optional
  504. An array (with dtype object) to output the geometries into.
  505. **kwargs
  506. See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
  507. Ignored if ``indices`` is provided.
  508. Notes
  509. -----
  510. .. deprecated:: 2.1.0
  511. A deprecation warning is shown if ``indices`` is specified as a
  512. positional argument. This will need to be specified as a keyword
  513. argument in a future release.
  514. See Also
  515. --------
  516. multipoints
  517. """
  518. typ = GeometryType.MULTILINESTRING
  519. geometries = np.asarray(geometries)
  520. if not isinstance(geometries, Geometry) and np.issubdtype(
  521. geometries.dtype, np.number
  522. ):
  523. geometries = linestrings(geometries)
  524. if indices is None:
  525. return lib.create_collection(geometries, np.intc(typ), out=out, **kwargs)
  526. else:
  527. return collections_1d(geometries, indices, typ, out=out)
  528. # Note: future plan is to change this signature over a few releases:
  529. # shapely 2.0:
  530. # multipolygons(geometries, indices=None, out=None, **kwargs)
  531. # shapely 2.1: shows deprecation warning about positional 'indices' arg
  532. # multipolygons(geometries, indices=None, *, out=None, **kwargs)
  533. # shapely 2.2(?): enforce keyword-only arguments after 'indices'
  534. # multipolygons(geometries, *, indices=None, out=None, **kwargs)
  535. @deprecate_positional(["indices"], category=DeprecationWarning)
  536. @multithreading_enabled
  537. def multipolygons(geometries, indices=None, *, out=None, **kwargs):
  538. """Create multipolygons from arrays of polygons.
  539. Parameters
  540. ----------
  541. geometries : array_like
  542. An array of polygons or coordinates (see polygons).
  543. indices : array_like, optional
  544. Indices into the target array where input geometries belong. If
  545. provided, both geometries and indices should be 1D and have matching
  546. sizes. Indices should be in increasing order. Missing indices result
  547. in a ValueError unless ``out`` is provided, in which case the original
  548. value in ``out`` is kept.
  549. out : ndarray, optional
  550. An array (with dtype object) to output the geometries into.
  551. **kwargs
  552. See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
  553. Ignored if ``indices`` is provided.
  554. Notes
  555. -----
  556. .. deprecated:: 2.1.0
  557. A deprecation warning is shown if ``indices`` is specified as a
  558. positional argument. This will need to be specified as a keyword
  559. argument in a future release.
  560. See Also
  561. --------
  562. multipoints
  563. """
  564. typ = GeometryType.MULTIPOLYGON
  565. geometries = np.asarray(geometries)
  566. if not isinstance(geometries, Geometry) and np.issubdtype(
  567. geometries.dtype, np.number
  568. ):
  569. geometries = polygons(geometries)
  570. if indices is None:
  571. return lib.create_collection(geometries, np.intc(typ), out=out, **kwargs)
  572. else:
  573. return collections_1d(geometries, indices, typ, out=out)
  574. # Note: future plan is to change this signature over a few releases:
  575. # shapely 2.0:
  576. # geometrycollections(geometries, indices=None, out=None, **kwargs)
  577. # shapely 2.1: shows deprecation warning about positional 'indices' arg
  578. # geometrycollections(geometries, indices=None, *, out=None, **kwargs)
  579. # shapely 2.2(?): enforce keyword-only arguments after 'indices'
  580. # geometrycollections(geometries, *, indices=None, out=None, **kwargs)
  581. @deprecate_positional(["indices"], category=DeprecationWarning)
  582. @multithreading_enabled
  583. def geometrycollections(geometries, indices=None, out=None, **kwargs):
  584. """Create geometrycollections from arrays of geometries.
  585. Parameters
  586. ----------
  587. geometries : array_like
  588. An array of geometries.
  589. indices : array_like, optional
  590. Indices into the target array where input geometries belong. If
  591. provided, both geometries and indices should be 1D and have matching
  592. sizes. Indices should be in increasing order. Missing indices result
  593. in a ValueError unless ``out`` is provided, in which case the original
  594. value in ``out`` is kept.
  595. out : ndarray, optional
  596. An array (with dtype object) to output the geometries into.
  597. **kwargs
  598. See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
  599. Ignored if ``indices`` is provided.
  600. Notes
  601. -----
  602. .. deprecated:: 2.1.0
  603. A deprecation warning is shown if ``indices`` is specified as a
  604. positional argument. This will need to be specified as a keyword
  605. argument in a future release.
  606. See Also
  607. --------
  608. multipoints
  609. """
  610. typ = GeometryType.GEOMETRYCOLLECTION
  611. if indices is None:
  612. return lib.create_collection(geometries, np.intc(typ), out=out, **kwargs)
  613. else:
  614. return collections_1d(geometries, indices, typ, out=out)
  615. def prepare(geometry, **kwargs):
  616. """Prepare a geometry, improving performance of other operations.
  617. A prepared geometry is a normal geometry with added information such as an
  618. index on the line segments. This improves the performance of the following
  619. operations: contains, contains_properly, covered_by, covers, crosses,
  620. disjoint, intersects, overlaps, touches, and within.
  621. Note that if a prepared geometry is modified, the newly created Geometry
  622. object is not prepared. In that case, ``prepare`` should be called again.
  623. This function does not recompute previously prepared geometries;
  624. it is efficient to call this function on an array that partially contains
  625. prepared geometries.
  626. This function does not return any values; geometries are modified in place.
  627. Parameters
  628. ----------
  629. geometry : Geometry or array_like
  630. Geometries are changed in place
  631. **kwargs
  632. See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
  633. See Also
  634. --------
  635. is_prepared : Identify whether a geometry is prepared already.
  636. destroy_prepared : Destroy the prepared part of a geometry.
  637. Examples
  638. --------
  639. >>> import shapely
  640. >>> from shapely import Point
  641. >>> poly = shapely.buffer(Point(1.0, 1.0), 1)
  642. >>> shapely.prepare(poly)
  643. >>> shapely.contains_properly(poly, [Point(0.0, 0.0), Point(0.5, 0.5)]).tolist()
  644. [False, True]
  645. """
  646. lib.prepare(geometry, **kwargs)
  647. def destroy_prepared(geometry, **kwargs):
  648. """Destroy the prepared part of a geometry, freeing up memory.
  649. Note that the prepared geometry will always be cleaned up if the geometry itself
  650. is dereferenced. This function needs only be called in very specific circumstances,
  651. such as freeing up memory without losing the geometries, or benchmarking.
  652. Parameters
  653. ----------
  654. geometry : Geometry or array_like
  655. Geometries are changed in-place
  656. **kwargs
  657. See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
  658. See Also
  659. --------
  660. prepare
  661. """
  662. lib.destroy_prepared(geometry, **kwargs)
  663. def empty(shape, geom_type=None, order="C"):
  664. """Create a geometry array prefilled with None or with empty geometries.
  665. Parameters
  666. ----------
  667. shape : int or tuple of int
  668. Shape of the empty array, e.g., ``(2, 3)`` or ``2``.
  669. geom_type : shapely.GeometryType, optional
  670. The desired geometry type in case the array should be prefilled
  671. with empty geometries. Default ``None``.
  672. order : {'C', 'F'}, optional, default: 'C'
  673. Whether to store multi-dimensional data in row-major
  674. (C-style) or column-major (Fortran-style) order in
  675. memory.
  676. Examples
  677. --------
  678. >>> import shapely
  679. >>> shapely.empty((2, 3)).tolist()
  680. [[None, None, None], [None, None, None]]
  681. >>> shapely.empty(2, geom_type=shapely.GeometryType.POINT).tolist()
  682. [<POINT EMPTY>, <POINT EMPTY>]
  683. """
  684. if geom_type is None:
  685. return np.empty(shape, dtype=object, order=order)
  686. geom_type = GeometryType(geom_type) # cast int to GeometryType
  687. if geom_type is GeometryType.MISSING:
  688. return np.empty(shape, dtype=object, order=order)
  689. fill_value = from_wkt(geom_type.name + " EMPTY")
  690. return np.full(shape, fill_value, dtype=object, order=order)