[![Banner](https://raw.githubusercontent.com/Oreilles/polars-st/main/assets/banner.svg)](#)
# Polars ST
Polars ST provides spatial operations on [Polars](https://github.com/pola-rs/polars) DataFrames, Series and Expressions. Just like [Shapely](https://github.com/shapely/shapely/) and [Geopandas](https://github.com/geopandas/geopandas), it make use of the library [GEOS](https://github.com/libgeos/geos), meaning that its API is mostly identical to theirs.
```pycon
>>> import polars as pl
>>> import polars_st as st
>>> gdf = st.GeoDataFrame([
... "POINT (0 0)",
... "LINESTRING (0 0, 1 1, 2 2)",
... "POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))",
... ])
>>> gdf.select(st.centroid().st.to_geojson())
┌──────────────────────────────────────────┐
│ geometry │
│ --- │
│ str │
╞══════════════════════════════════════════╡
│ {"type":"Point","coordinates":[0.0,0.0]} │
│ {"type":"Point","coordinates":[1.0,1.0]} │
│ {"type":"Point","coordinates":[0.5,0.5]} │
└──────────────────────────────────────────┘
```
## Installation
Polars ST is published on PyPi so you can install it with your preferred package manager.
```sh
pip install polars-st
```
## How it works
Geometries are stored as EWKB in regular Polars Binary columns. EWKB is a extension to the WKB standard popularized by PostGIS, that can also store information about the CRS of each geometry as an integer code called SRID.
For every spatial operations, the WKB binary blob will be parsed into a Geometry object so the operation can be done. If the operation result is a geometry, it will then be serialized back to EWKB. Because of that round-trip, some operations might turn out to be slower than GeoPandas. In most cases however, the performance penalty of that round-trip will be marginal compared to the spatial operation, and you will fully benefit from the parallelization capabilities of Polars.
## About GeoPolars
[GeoPolars](https://github.com/geopolars/geopolars) is an incredibly promising tool for manipulating geographic data in Polars based on [GeoArrow](https://github.com/geoarrow/geoarrow) that likely will outperform this library's performance by a long shot. It however seems to be quite a long way from being ready and feature-complete, mostly due to Polars lack of support for [Arrow Extension Types](https://github.com/pola-rs/polars/issues/9112) and [subclassing of core datatypes](https://github.com/pola-rs/polars/issues/2846#issuecomment-1711799869).
Storing geometry as EWKB and delegating core functionality to GEOS allows `polars-st` to be ready now, and provide additional features such as XYZM coordinates, curved geometry types and per-geometry CRS information.
I really hope Geopolars get there soon, and that maybe some of the API design explorations made here will have helped make it even more pleasant to use.
## About Polars
This project is not affiliated with Polars. The design language was made very close to that of Polars because I found it amazingly appealing and liked the challenge of adding geographic meaning to it, and to also hilight the fact that this project is an exclusive extension to Polars.
## About GEOS
In order to save myself (and yourself) from the burden of GEOS version-specific features and bugs, `polars-st` statically link to GEOS `main`. This means that all documented features are guaranteed to be available. This also means that this project is LGPL licensed, the same way GEOS is.
## License
Copyright (C) 2024 Aurèle Ferotin
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
Raw data
{
"_id": null,
"home_page": null,
"name": "polars-st",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "polars, dataframe, gis, geospatial, geometry",
"author": null,
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/10/05/b119e78ebfa53caba58f875cc594d41637a9ee870948e7a56fc96b2b94ef/polars_st-0.1.0a10.tar.gz",
"platform": null,
"description": "[![Banner](https://raw.githubusercontent.com/Oreilles/polars-st/main/assets/banner.svg)](#)\n\n# Polars ST\n\nPolars ST provides spatial operations on [Polars](https://github.com/pola-rs/polars) DataFrames, Series and Expressions. Just like [Shapely](https://github.com/shapely/shapely/) and [Geopandas](https://github.com/geopandas/geopandas), it make use of the library [GEOS](https://github.com/libgeos/geos), meaning that its API is mostly identical to theirs.\n\n```pycon\n>>> import polars as pl\n>>> import polars_st as st\n>>> gdf = st.GeoDataFrame([\n... \"POINT (0 0)\",\n... \"LINESTRING (0 0, 1 1, 2 2)\",\n... \"POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))\",\n... ])\n>>> gdf.select(st.centroid().st.to_geojson())\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 geometry \u2502\n\u2502 --- \u2502\n\u2502 str \u2502\n\u255e\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2561\n\u2502 {\"type\":\"Point\",\"coordinates\":[0.0,0.0]} \u2502\n\u2502 {\"type\":\"Point\",\"coordinates\":[1.0,1.0]} \u2502\n\u2502 {\"type\":\"Point\",\"coordinates\":[0.5,0.5]} \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n## Installation\n\nPolars ST is published on PyPi so you can install it with your preferred package manager.\n\n```sh\npip install polars-st\n```\n\n## How it works\n\nGeometries are stored as EWKB in regular Polars Binary columns. EWKB is a extension to the WKB standard popularized by PostGIS, that can also store information about the CRS of each geometry as an integer code called SRID.\n\nFor every spatial operations, the WKB binary blob will be parsed into a Geometry object so the operation can be done. If the operation result is a geometry, it will then be serialized back to EWKB. Because of that round-trip, some operations might turn out to be slower than GeoPandas. In most cases however, the performance penalty of that round-trip will be marginal compared to the spatial operation, and you will fully benefit from the parallelization capabilities of Polars.\n\n\n## About GeoPolars\n\n[GeoPolars](https://github.com/geopolars/geopolars) is an incredibly promising tool for manipulating geographic data in Polars based on [GeoArrow](https://github.com/geoarrow/geoarrow) that likely will outperform this library's performance by a long shot. It however seems to be quite a long way from being ready and feature-complete, mostly due to Polars lack of support for [Arrow Extension Types](https://github.com/pola-rs/polars/issues/9112) and [subclassing of core datatypes](https://github.com/pola-rs/polars/issues/2846#issuecomment-1711799869).\n\nStoring geometry as EWKB and delegating core functionality to GEOS allows `polars-st` to be ready now, and provide additional features such as XYZM coordinates, curved geometry types and per-geometry CRS information.\n\nI really hope Geopolars get there soon, and that maybe some of the API design explorations made here will have helped make it even more pleasant to use.\n\n## About Polars\n\nThis project is not affiliated with Polars. The design language was made very close to that of Polars because I found it amazingly appealing and liked the challenge of adding geographic meaning to it, and to also hilight the fact that this project is an exclusive extension to Polars.\n\n\n## About GEOS\n\nIn order to save myself (and yourself) from the burden of GEOS version-specific features and bugs, `polars-st` statically link to GEOS `main`. This means that all documented features are guaranteed to be available. This also means that this project is LGPL licensed, the same way GEOS is.\n\n## License\n\nCopyright (C) 2024 Aur\u00e8le Ferotin\n\nThis library is free software; you can redistribute it and/or\nmodify it under the terms of the GNU Lesser General Public\nLicense as published by the Free Software Foundation; either\nversion 2.1 of the License, or (at your option) any later version.\n\nThis library is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\nLesser General Public License for more details.\n\nYou should have received a copy of the GNU Lesser General Public\nLicense along with this library; if not, write to the Free Software\nFoundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301\nUSA\n\n",
"bugtrack_url": null,
"license": "LGPL-2.1",
"summary": "Spatial extension for Polars DataFrames",
"version": "0.1.0a10",
"project_urls": {
"Source Code": "https://github.com/Oreilles/polars-st"
},
"split_keywords": [
"polars",
" dataframe",
" gis",
" geospatial",
" geometry"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "2ac4c04d665d99bdb9f79b829c64e34fed697f4a98ed1866df908ec9f7ee1ca6",
"md5": "5c2c29a973a1e94ce9228eeecf067efb",
"sha256": "877632fbdb242952d5560e50cd6b8be7637ac686e5504a48c735c0ae181aa302"
},
"downloads": -1,
"filename": "polars_st-0.1.0a10-cp38-abi3-macosx_10_12_x86_64.whl",
"has_sig": false,
"md5_digest": "5c2c29a973a1e94ce9228eeecf067efb",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.10",
"size": 10375494,
"upload_time": "2024-11-18T11:13:33",
"upload_time_iso_8601": "2024-11-18T11:13:33.620259Z",
"url": "https://files.pythonhosted.org/packages/2a/c4/c04d665d99bdb9f79b829c64e34fed697f4a98ed1866df908ec9f7ee1ca6/polars_st-0.1.0a10-cp38-abi3-macosx_10_12_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "078ee67d3872097d60e42926e6190fe7590b7f9c8340e28fb19216b8d6ad9a1a",
"md5": "3aba84394a9477b1651fc64745145de1",
"sha256": "8805985f96b4841add0d638da0cfb16cca31f4a15f043055fe6fe75003dd12a7"
},
"downloads": -1,
"filename": "polars_st-0.1.0a10-cp38-abi3-macosx_11_0_arm64.whl",
"has_sig": false,
"md5_digest": "3aba84394a9477b1651fc64745145de1",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.10",
"size": 9360050,
"upload_time": "2024-11-18T11:13:30",
"upload_time_iso_8601": "2024-11-18T11:13:30.954757Z",
"url": "https://files.pythonhosted.org/packages/07/8e/e67d3872097d60e42926e6190fe7590b7f9c8340e28fb19216b8d6ad9a1a/polars_st-0.1.0a10-cp38-abi3-macosx_11_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "0b21f36352b9e49428bf0ed7569cc0260b2a93dfac5aa394692c479f47657916",
"md5": "f521dc54c8f9771d0efd3f4d6cd4df9e",
"sha256": "1405ba5b5626d97c550175dc7bd5daa85b3cc1fc824c6474c5ec6277e54be1a2"
},
"downloads": -1,
"filename": "polars_st-0.1.0a10-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"has_sig": false,
"md5_digest": "f521dc54c8f9771d0efd3f4d6cd4df9e",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.10",
"size": 9802644,
"upload_time": "2024-11-18T11:13:18",
"upload_time_iso_8601": "2024-11-18T11:13:18.897582Z",
"url": "https://files.pythonhosted.org/packages/0b/21/f36352b9e49428bf0ed7569cc0260b2a93dfac5aa394692c479f47657916/polars_st-0.1.0a10-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "ea60b26adbafaf100f0953457de9d6f615b832d94850332ed782bc45761087ac",
"md5": "8970526481364b92d8ae080dfcc3b910",
"sha256": "a76d67d04a1ef3072d80d6ed2c8791568cedb9e118319c49d8e1f52d0f0a37ee"
},
"downloads": -1,
"filename": "polars_st-0.1.0a10-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",
"has_sig": false,
"md5_digest": "8970526481364b92d8ae080dfcc3b910",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.10",
"size": 9828774,
"upload_time": "2024-11-18T11:13:21",
"upload_time_iso_8601": "2024-11-18T11:13:21.529653Z",
"url": "https://files.pythonhosted.org/packages/ea/60/b26adbafaf100f0953457de9d6f615b832d94850332ed782bc45761087ac/polars_st-0.1.0a10-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "49c2837e56ced95077f41f4ab08b280a80c3866917ce6f083e67cc07a9b7657a",
"md5": "8f9c42af96925ea53c647ba0e1e5bfd6",
"sha256": "fcb8f4671627965e1962ead64a7284c559195c8343bde904f64bf7213298167f"
},
"downloads": -1,
"filename": "polars_st-0.1.0a10-cp38-abi3-manylinux_2_17_i686.manylinux2014_i686.whl",
"has_sig": false,
"md5_digest": "8f9c42af96925ea53c647ba0e1e5bfd6",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.10",
"size": 11859861,
"upload_time": "2024-11-18T11:13:24",
"upload_time_iso_8601": "2024-11-18T11:13:24.891673Z",
"url": "https://files.pythonhosted.org/packages/49/c2/837e56ced95077f41f4ab08b280a80c3866917ce6f083e67cc07a9b7657a/polars_st-0.1.0a10-cp38-abi3-manylinux_2_17_i686.manylinux2014_i686.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "03198347f0fdb4708ad4b0d720600ba453273070dc186dce97215bcf62a6a6fc",
"md5": "fa0a891d643b2448e6aa8b0229dee537",
"sha256": "8d5efbdde26b9f8aa063a58b2e7829907401c8cac516038a554a08a6d035403c"
},
"downloads": -1,
"filename": "polars_st-0.1.0a10-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "fa0a891d643b2448e6aa8b0229dee537",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.10",
"size": 10801986,
"upload_time": "2024-11-18T11:13:27",
"upload_time_iso_8601": "2024-11-18T11:13:27.647515Z",
"url": "https://files.pythonhosted.org/packages/03/19/8347f0fdb4708ad4b0d720600ba453273070dc186dce97215bcf62a6a6fc/polars_st-0.1.0a10-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "4dde5b7c1ce62bd5ee677629f2a92c1f9429ae942f9ba9423b2c1a0fafba0490",
"md5": "e2b5cbc00eaef4c46c45be6c66b73e10",
"sha256": "a6d47ba28f6c3721659369f4d43003f3e17d0953dab47155efec856cfc7c2a88"
},
"downloads": -1,
"filename": "polars_st-0.1.0a10-cp38-abi3-musllinux_1_2_aarch64.whl",
"has_sig": false,
"md5_digest": "e2b5cbc00eaef4c46c45be6c66b73e10",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.10",
"size": 9623127,
"upload_time": "2024-11-18T11:13:36",
"upload_time_iso_8601": "2024-11-18T11:13:36.530524Z",
"url": "https://files.pythonhosted.org/packages/4d/de/5b7c1ce62bd5ee677629f2a92c1f9429ae942f9ba9423b2c1a0fafba0490/polars_st-0.1.0a10-cp38-abi3-musllinux_1_2_aarch64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "8fed6b201b1f7e0a5369fc2b31397ea05b7c755d439a5496647e03a120e35c90",
"md5": "6a508675ef7c500e1dcc6f1ce457262a",
"sha256": "753ac36907c12d5e731f83aefb3cd2e26084c217396c74b89441e5c73173c3cc"
},
"downloads": -1,
"filename": "polars_st-0.1.0a10-cp38-abi3-musllinux_1_2_armv7l.whl",
"has_sig": false,
"md5_digest": "6a508675ef7c500e1dcc6f1ce457262a",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.10",
"size": 9824458,
"upload_time": "2024-11-18T11:13:41",
"upload_time_iso_8601": "2024-11-18T11:13:41.043942Z",
"url": "https://files.pythonhosted.org/packages/8f/ed/6b201b1f7e0a5369fc2b31397ea05b7c755d439a5496647e03a120e35c90/polars_st-0.1.0a10-cp38-abi3-musllinux_1_2_armv7l.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "0f3b3cc6c58eb39b642b77a4129ac50cd4c516fe5c06490dc94317ee8961df78",
"md5": "019ad7ae6f4109d1b0f3e76af9a86427",
"sha256": "9e513f7e74c127ea954faa756255a2ca1f79d344b35b8c7f72679f878e2460e4"
},
"downloads": -1,
"filename": "polars_st-0.1.0a10-cp38-abi3-musllinux_1_2_i686.whl",
"has_sig": false,
"md5_digest": "019ad7ae6f4109d1b0f3e76af9a86427",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.10",
"size": 11279264,
"upload_time": "2024-11-18T11:13:44",
"upload_time_iso_8601": "2024-11-18T11:13:44.719271Z",
"url": "https://files.pythonhosted.org/packages/0f/3b/3cc6c58eb39b642b77a4129ac50cd4c516fe5c06490dc94317ee8961df78/polars_st-0.1.0a10-cp38-abi3-musllinux_1_2_i686.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "b59b9bca749fba20b109b95f5d310ee89c62c8e37f1311f09433b4dcb18901d8",
"md5": "75e0194ddb090881438e8fbcb6040114",
"sha256": "75d55fe8b98ee7e9ab1f55d6bf8d62e425fc9577f295b9b3a61384924fcfb6b6"
},
"downloads": -1,
"filename": "polars_st-0.1.0a10-cp38-abi3-musllinux_1_2_x86_64.whl",
"has_sig": false,
"md5_digest": "75e0194ddb090881438e8fbcb6040114",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.10",
"size": 10794973,
"upload_time": "2024-11-18T11:13:47",
"upload_time_iso_8601": "2024-11-18T11:13:47.931778Z",
"url": "https://files.pythonhosted.org/packages/b5/9b/9bca749fba20b109b95f5d310ee89c62c8e37f1311f09433b4dcb18901d8/polars_st-0.1.0a10-cp38-abi3-musllinux_1_2_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "1005b119e78ebfa53caba58f875cc594d41637a9ee870948e7a56fc96b2b94ef",
"md5": "9c74eb4327c2a8ef25eb0571c15cff7f",
"sha256": "79cd9c9971129d34449184a9682d99f93d2670f7033a0bdda4b15ceefad19e16"
},
"downloads": -1,
"filename": "polars_st-0.1.0a10.tar.gz",
"has_sig": false,
"md5_digest": "9c74eb4327c2a8ef25eb0571c15cff7f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 164518,
"upload_time": "2024-11-18T11:13:50",
"upload_time_iso_8601": "2024-11-18T11:13:50.900926Z",
"url": "https://files.pythonhosted.org/packages/10/05/b119e78ebfa53caba58f875cc594d41637a9ee870948e7a56fc96b2b94ef/polars_st-0.1.0a10.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-18 11:13:50",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Oreilles",
"github_project": "polars-st",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "polars-st"
}