Skip to main content

utiles = (utils + tiles) * rust

Project description

utiles (python)

PyPI Python Version from PEP 621 TOML Wheel

utiles = utils + tiles

Fast spherical mercator geo/tile util(e)ities.

A mostly drop-in replacement for mercantile written w/ rust, plus several other util(e)ities.

Installation

pip install utiles

Usage

>>> import utiles as ut
>>> ut.bounds(1, 1, 1)
LngLatBbox(west=0, south=-85.0511287798066, east=180, north=0)
>>> t = ut.Tile(1, 2, 3)
>>> t
Tile(x=1, y=2, z=3)
>>> t.x, t.y, t.z
(1, 2, 3)
>>> x, y, z = t
>>> (x, y, z)
(1, 2, 3)
>>> list(ut.tiles(*ut.bounds(1, 1, 1), 3))
[Tile(x=4, y=4, z=3), Tile(x=4, y=5, z=3), Tile(x=4, y=6, z=3), Tile(x=4, y=7, z=3), Tile(x=5, y=4, z=3), Tile(x=5, y=5, z=3), Tile(x=5, y=6, z=3), Tile(x=5, y=7, z=3), Tile(x=6, y=4, z=3), Tile(x=6, y=5, z=3), Tile(x=6, y=6, z=3), Tile(x=6, y=7, z=3), Tile(x=7, y=4, z=3), Tile(x=7, y=5, z=3), Tile(x=7, y=6, z=3), Tile(x=7, y=7, z=3)]
>>> t
Tile(x=1, y=2, z=3)
>>> t.parent()
Tile(x=0, y=1, z=2)
>>> t.children()
[Tile(x=2, y=4, z=4), Tile(x=3, y=4, z=4), Tile(x=3, y=5, z=4), Tile(x=2, y=5, z=4)]
>>> t.bounds()
LngLatBbox(west=-135, south=40.97989806962013, east=-90, north=66.51326044311186)
>>> t.ul()
LngLat(lng=-135, lat=66.51326044311186)
>>> t.asdict()
{'x': 1, 'y': 2, 'z': 3}
>>> t.center()
LngLat(lng=-112.5, lat=53.74657925636599)
>>> ~t
Tile(x=1, y=5, z=3)
>>> t.valid()  # check if tile is valid
True
>>> ut.Tile(1000, 1231234124, 2).valid()  # invalid tile
False
>>> t.pmtileid()  # return the pmtileid of the tile
34
>>> ut.Tile.from_pmtileid(34)  # create a tile from pmtileid
Tile(x=1, y=2, z=3)
>>> t.json_arr()  # json-array string
'[1, 2, 3]'
>>> t.json_obj()  # json-object string
'{"x":1,"y":2,"z":3}'
>>> t.fmt_zxy()  # format tile as z/x/y
'3/1/2'
>>> t.fmt_zxy_ext('png')  # format tile as z/x/y.ext
'3/1/2.png'
>>> t == (1, 2, 3)  # compare with tuple
True
>>> t == (1, 2, 2234234)  # compare with tuple
False

About

Why?

I use mercantile regularly and wished it were a bit more ergonomic, had type annotations, and was faster, but overall it's a great library.

This was an excuse to learn some more rust as well as pyo3.

Do I/you REALLY need a rust-port of mercantile?

I don't know, decide for yourself. utiles is certainly faster than mercantile for some things (see benchmarks below)

Is it really a drop in replacement for mercantile?

Not quite, but it's close. utiles doesn't throw the same exceptions as mercantile, instead it throws ValueError's and TypeError's.

There might be other differences, but I have been using it instead of mercantile for a bit now and it works pretty decent, tho I am open to suggestions!

Benchmarks (WIP)

---------------------------------------------------------------------------------------------------- benchmark 'quadkey': 12 tests -----------------------------------------------------------------------------------------------------
Name (time in ns)                                        Min                     Max                  Mean              StdDev                Median                 IQR            Outliers  OPS (Kops/s)            Rounds  Iterations
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_quadkey_bench[utiles-(0, 0, 0)]                199.9942 (1.0)       47,100.0021 (8.78)       284.7909 (1.0)      315.1058 (6.70)       299.9950 (1.06)     100.0008 (>1000.0)  966;1164    3,511.3476 (1.0)       38911           1
test_quadkey_bench[utiles-(1, 1, 1)]                252.6316 (1.26)       5,363.1581 (1.0)        293.9171 (1.03)      47.0478 (1.0)        284.2108 (1.0)       10.5264 (>1000.0)2884;35689    3,402.3204 (0.97)     196079          19
test_quadkey_bench[utiles-(1, 0, 1)]                299.9950 (1.50)      86,300.0023 (16.09)      397.2831 (1.39)     383.5726 (8.15)       399.9958 (1.41)       0.0073 (1.0)    1451;22409    2,517.0967 (0.72)      99010           1
test_quadkey_bench[mercantile-(0, 0, 0)]            599.9973 (3.00)      28,200.0037 (5.26)       821.2744 (2.88)     301.0209 (6.40)       799.9988 (2.81)       0.0073 (1.0)     658;21559    1,217.6198 (0.35)      69445           1
test_quadkey_bench[utiles-(1, 40, 7)]               599.9973 (3.00)     136,899.9947 (25.53)      758.0325 (2.66)     676.4311 (14.38)      699.9981 (2.46)       0.0073 (1.0)     565;29079    1,319.2047 (0.38)     108696           1
test_quadkey_bench[utiles-(486, 332, 10)]           749.9999 (3.75)       8,055.0002 (1.50)       838.5705 (2.94)     137.5439 (2.92)       824.9997 (2.90)      23.7496 (>1000.0) 1445;4742    1,192.5056 (0.34)      63695          20
test_quadkey_bench[mercantile-(1, 0, 1)]            799.9988 (4.00)     104,300.0011 (19.45)    1,015.6996 (3.57)     539.0831 (11.46)    1,000.0003 (3.52)       0.0073 (1.0)    1217;51791      984.5431 (0.28)     119048           1
test_quadkey_bench[mercantile-(1, 1, 1)]            799.9988 (4.00)      75,999.9966 (14.17)    1,047.5805 (3.68)     419.8019 (8.92)     1,000.0003 (3.52)     100.0008 (>1000.0) 3366;4074      954.5806 (0.27)     166667           1
test_quadkey_bench[utiles-(486, 332, 20)]         1,299.9953 (6.50)      83,399.9948 (15.55)    1,545.1801 (5.43)     461.2615 (9.80)     1,499.9969 (5.28)     100.0008 (>1000.0)8793;17328      647.1738 (0.18)     163935           1
test_quadkey_bench[mercantile-(1, 40, 7)]         1,599.9976 (8.00)     110,599.9982 (20.62)    1,789.4247 (6.28)     711.1950 (15.12)    1,799.9992 (6.33)     100.0008 (>1000.0) 1599;2703      558.8388 (0.16)     116280           1
test_quadkey_bench[mercantile-(486, 332, 10)]     1,999.9934 (10.00)    117,000.0032 (21.82)    2,353.1110 (8.26)     768.5591 (16.34)    2,300.0030 (8.09)     200.0015 (>1000.0) 1917;2168      424.9693 (0.12)     117648           1
test_quadkey_bench[mercantile-(486, 332, 20)]     3,199.9953 (16.00)     66,100.0013 (12.32)    3,601.3369 (12.65)    567.1348 (12.05)    3,599.9983 (12.67)    100.0080 (>1000.0) 1479;4347      277.6747 (0.08)      97088           1
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------- benchmark 'tiles': 2 tests ---------------------------------------------------------------------------------------------
Name (time in us)                           Min                   Max                  Mean              StdDev                Median                 IQR            Outliers         OPS            Rounds  Iterations
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_tiles_gen_bench[utiles]           239.3000 (1.0)      1,597.3000 (1.0)        308.5684 (1.0)      130.3316 (1.0)        267.2000 (1.0)       16.5000 (1.0)       312;559  3,240.7721 (1.0)        3232           1
test_tiles_gen_bench[mercantile]     1,349.9000 (5.64)     7,159.2000 (4.48)     1,798.2186 (5.83)     779.7610 (5.98)     1,526.7000 (5.71)     149.6250 (9.07)       66;111    556.1059 (0.17)        601           1
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

------------------------------------------------------------------------------------------------------- benchmark 'ul': 12 tests ------------------------------------------------------------------------------------------------------
Name (time in ns)                                   Min                     Max                  Mean                StdDev                Median                 IQR              Outliers  OPS (Kops/s)            Rounds  Iterations
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_ul_bench[utiles-(1, 1, 1)]                204.3478 (1.0)        7,160.8697 (1.0)        263.7100 (1.0)        125.3400 (1.00)       221.7392 (1.0)       26.0868 (1.30)    17101;28014    3,792.0436 (1.0)      169492          23
test_ul_bench[utiles-(1, 0, 1)]                229.9999 (1.13)      10,579.9998 (1.48)       273.2589 (1.04)       124.7846 (1.0)        250.0001 (1.13)      20.0002 (1.0)      9266;14360    3,659.5327 (0.97)     188680          20
test_ul_bench[utiles-(1, 40, 7)]               229.9999 (1.13)      42,870.0001 (5.99)       311.4689 (1.18)       188.2129 (1.51)       255.0001 (1.15)      35.0003 (1.75)    16764;39465    3,210.5932 (0.85)     200000          20
test_ul_bench[utiles-(486, 332, 20)]           229.9999 (1.13)      65,699.9997 (9.17)       318.4368 (1.21)       243.5307 (1.95)       259.9998 (1.17)      35.0003 (1.75)    11008;36596    3,140.3404 (0.83)     178572          20
test_ul_bench[utiles-(0, 0, 0)]                299.9950 (1.47)      33,899.9962 (4.73)       349.3773 (1.32)       205.0577 (1.64)       300.0023 (1.35)     100.0008 (5.00)        618;618    2,862.2349 (0.75)      70423           1
test_ul_bench[utiles-(486, 332, 10)]           299.9950 (1.47)      57,999.9978 (8.10)       403.1283 (1.53)       400.2343 (3.21)       399.9958 (1.80)     100.0008 (5.00)     2013;20449    2,480.5998 (0.65)     192308           1
test_ul_bench[mercantile-(0, 0, 0)]            999.9931 (4.89)     206,099.9977 (28.78)    1,296.5665 (4.92)     1,201.7776 (9.63)     1,200.0019 (5.41)     100.0008 (5.00)       387;2129      771.2678 (0.20)      45872           1
test_ul_bench[mercantile-(1, 0, 1)]            999.9931 (4.89)     166,500.0018 (23.25)    1,288.3700 (4.89)       712.6090 (5.71)     1,299.9953 (5.86)     100.0008 (5.00)      2119;3450      776.1746 (0.20)     147059           1
test_ul_bench[mercantile-(1, 1, 1)]          1,000.0003 (4.89)     102,799.9970 (14.36)    1,253.0401 (4.75)       570.2565 (4.57)     1,200.0019 (5.41)     100.0008 (5.00)      2957;3697      798.0590 (0.21)     144928           1
test_ul_bench[mercantile-(1, 40, 7)]         1,000.0003 (4.89)      89,599.9983 (12.51)    1,263.1955 (4.79)       586.9464 (4.70)     1,200.0019 (5.41)     100.0008 (5.00)      1775;2965      791.6431 (0.21)     166667           1
test_ul_bench[mercantile-(486, 332, 10)]     1,099.9938 (5.38)      90,200.0029 (12.60)    1,327.0801 (5.03)       536.7494 (4.30)     1,299.9953 (5.86)     100.0008 (5.00)      6813;7956      753.5340 (0.20)     135136           1
test_ul_bench[mercantile-(486, 332, 20)]     1,099.9938 (5.38)     107,300.0021 (14.98)    1,264.2361 (4.79)       594.6154 (4.77)     1,200.0019 (5.41)     100.0008 (5.00)      1522;2265      790.9915 (0.21)     123457           1
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

TODO:

  • benchmark against mercantile
  • Re-write cli in rust with clap
  • Maybe:
    • [] Mbtiles support??
    • [] Reading/writing mvt files?

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

utiles-0.4.1.tar.gz (120.8 kB view hashes)

Uploaded Source

Built Distributions

utiles-0.4.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.5 MB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ x86-64

utiles-0.4.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (3.1 MB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ ARMv7l

utiles-0.4.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.2 MB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ ARM64

utiles-0.4.1-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.whl (3.5 MB view hashes)

Uploaded PyPy manylinux: glibc 2.12+ i686

utiles-0.4.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.5 MB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ x86-64

utiles-0.4.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (3.1 MB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ ARMv7l

utiles-0.4.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.2 MB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ ARM64

utiles-0.4.1-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.whl (3.5 MB view hashes)

Uploaded PyPy manylinux: glibc 2.12+ i686

utiles-0.4.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.5 MB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ x86-64

utiles-0.4.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (3.1 MB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ ARMv7l

utiles-0.4.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.2 MB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ ARM64

utiles-0.4.1-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl (3.5 MB view hashes)

Uploaded PyPy manylinux: glibc 2.12+ i686

utiles-0.4.1-cp312-none-win_amd64.whl (3.5 MB view hashes)

Uploaded CPython 3.12 Windows x86-64

utiles-0.4.1-cp312-none-win32.whl (3.0 MB view hashes)

Uploaded CPython 3.12 Windows x86

utiles-0.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.5 MB view hashes)

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64

utiles-0.4.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (3.1 MB view hashes)

Uploaded CPython 3.12 manylinux: glibc 2.17+ ARMv7l

utiles-0.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.2 MB view hashes)

Uploaded CPython 3.12 manylinux: glibc 2.17+ ARM64

utiles-0.4.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl (3.5 MB view hashes)

Uploaded CPython 3.12 manylinux: glibc 2.12+ i686

utiles-0.4.1-cp312-cp312-macosx_11_0_arm64.whl (3.1 MB view hashes)

Uploaded CPython 3.12 macOS 11.0+ ARM64

utiles-0.4.1-cp312-cp312-macosx_10_12_x86_64.whl (3.4 MB view hashes)

Uploaded CPython 3.12 macOS 10.12+ x86-64

utiles-0.4.1-cp311-none-win_amd64.whl (3.4 MB view hashes)

Uploaded CPython 3.11 Windows x86-64

utiles-0.4.1-cp311-none-win32.whl (3.0 MB view hashes)

Uploaded CPython 3.11 Windows x86

utiles-0.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.5 MB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

utiles-0.4.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (3.1 MB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ARMv7l

utiles-0.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.2 MB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ARM64

utiles-0.4.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl (3.5 MB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.12+ i686

utiles-0.4.1-cp311-cp311-macosx_11_0_arm64.whl (3.1 MB view hashes)

Uploaded CPython 3.11 macOS 11.0+ ARM64

utiles-0.4.1-cp311-cp311-macosx_10_12_x86_64.whl (3.4 MB view hashes)

Uploaded CPython 3.11 macOS 10.12+ x86-64

utiles-0.4.1-cp310-none-win_amd64.whl (3.4 MB view hashes)

Uploaded CPython 3.10 Windows x86-64

utiles-0.4.1-cp310-none-win32.whl (3.0 MB view hashes)

Uploaded CPython 3.10 Windows x86

utiles-0.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.5 MB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

utiles-0.4.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (3.1 MB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ARMv7l

utiles-0.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.2 MB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ARM64

utiles-0.4.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl (3.5 MB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.12+ i686

utiles-0.4.1-cp310-cp310-macosx_11_0_arm64.whl (3.1 MB view hashes)

Uploaded CPython 3.10 macOS 11.0+ ARM64

utiles-0.4.1-cp310-cp310-macosx_10_12_x86_64.whl (3.4 MB view hashes)

Uploaded CPython 3.10 macOS 10.12+ x86-64

utiles-0.4.1-cp39-none-win_amd64.whl (3.4 MB view hashes)

Uploaded CPython 3.9 Windows x86-64

utiles-0.4.1-cp39-none-win32.whl (3.0 MB view hashes)

Uploaded CPython 3.9 Windows x86

utiles-0.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.5 MB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

utiles-0.4.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (3.1 MB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.17+ ARMv7l

utiles-0.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.2 MB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.17+ ARM64

utiles-0.4.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl (3.5 MB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.12+ i686

utiles-0.4.1-cp38-none-win_amd64.whl (3.4 MB view hashes)

Uploaded CPython 3.8 Windows x86-64

utiles-0.4.1-cp38-none-win32.whl (3.0 MB view hashes)

Uploaded CPython 3.8 Windows x86

utiles-0.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.5 MB view hashes)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

utiles-0.4.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (3.1 MB view hashes)

Uploaded CPython 3.8 manylinux: glibc 2.17+ ARMv7l

utiles-0.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.2 MB view hashes)

Uploaded CPython 3.8 manylinux: glibc 2.17+ ARM64

utiles-0.4.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl (3.5 MB view hashes)

Uploaded CPython 3.8 manylinux: glibc 2.12+ i686

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page