Package: zCurve
zCurvezCurve is a Python module with methods to efficiently map multidimensional data to a single dimension while preserving locality of the data points.This mapping is commonly known as Z-order, Lebesgue curve, Morton space filling curve, Morton order or Morton code.Image by David Eppstein, 2008The Morton code of a multi-dimensional data point is calculated by bitwise interlacing the binary representations of its coordinate values.zCurve provides two functions for handling the encoding and decoding of data points witharbitrarydimensionality andarbitrarycoordinate size:interlace(*data_point:int,dims:int=None,bits_per_dim:int=None)->intdeinterlace(code_point:int,dims:int=3)->List[int]When handling large multi-dimensional dataset (n > 10.000), zCurve offers some simple  but convenient means of parallelizing the Morton encoding and decoding:par_interlace(data_points:List[List[int]],dims:int=None,bits_per_dim:int=None)->List[int]par_deinterlace(code_points:List[int],dims:int=3)->List[List[int]]Given the Morton codes of a multi-dimensional dataset, we can perform multi-dimensional range search using only a one-dimensional data structure.
For range searching, zCurve offers two functions for calculating the necesaaryLITMAXandBIGMINvalues:prev_morton(code_point:int,rmin_code:int,rmax_code:int,dims:int=3)->intnext_morton(code_point:int,rmin_code:int,rmax_code:int,dims:int=3)->intThis implementation is based on the following paperTropf, Herbert, and Helmut Herzog. "Multidimensional Range Search in Dynamically Balanced Trees." ANGEWANDTE INFO. 2 (1981): 71-77.and it makes heavy use of the excellentgmpy2 module.InstallationpipinstallzCurveUsageBasicsimportzCurveaszimports the module.code=z.interlace(2,16,8)interlaces the 3D data point(2,16,8)into Morton code point10248.When explicitly specify dimensionality and bits per dimension of your data pointcode=z.interlace(2,16,8,dims=3,bits_per_dim=5)performance will benefit substantially.z.deinterlace(4711)deinterlaces the Morton code point4711into the 3D data point(29,1,3).Parallel interlacing/deinterlacingGiven a potentially large list of n-dimensionaldata_pointsfromrandomimportrandrangebit_size=16max_val=2**bit_size-1no_samples=10**6data_points=[(randrange(0,max_val),randrange(0,max_val),randrange(0,max_val))foriinrange(no_samples)]we can speed up things by usingpar_interlaceandpar_deinterlacemorton_codes=z.par_interlace(data_points,dims=3,bits_per_dim=16)data_points==z.par_deinterlaces(morton_codes,dims=3)Range searchingImage by Tropf and Herzog, 1981When range searching, we can prune the search space by calculatingBIGMIN(aka "GetNextZ-address") andLITMAX(aka "GetPrevZ-address") values.point=z.interlace(6,3,dims=2)# => 30rmin=z.interlace(5,3,dims=2)# => 27rmax=z.interlace(10,5,dims=2)# => 102BIGMIN=z.next_morton(point,rmin,rmax,dims=2)# => 31LITMAX=z.prev_morton(point,rmin,rmax,dims=2)# => 27In addition, we can easily check if a given Morton code point is within a specified rangez.in_range(58,27,102,dims=2)# => Falsez.in_range(49,27,102,dims=2)# => TrueCitation@misc{rmrschub_2021_zCurve,author={René Schubotz},title={{zCurve: Multi-dimensional indexing using Morton space filling curves.}},month=may,year=2021,doi={10.5281/zenodo.4777584},version={0.0.4},publisher={Zenodo},url={https://github.com/rmrschub/zCurve}}LicenseThis work is licensed under aCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.