利用hilbert曲线确定lng/lat坐标。
geohash-hilbert的Python项目详细描述
Geohash希尔伯特
使用hilbert空间填充曲线的geohash a lng/lat坐标。
In[1]:importgeohash_hilbertasghhIn[2]:ghh.encode(6.957036,50.941291)Out[2]:'Z7fe2GaIVO'In[3]:ghh.decode('Z7fe2GaIVO')Out[3]:(6.957036126405001,50.941291032359004)In[4]:ghh.decode_exactly('Z7fe2GaIVO')Out[4]:(6.957036126405001,50.941291032359004,# position1.6763806343078613e-07,8.381903171539307e-08)# errorsIn[5]:ghh.encode?Signature:ghh.encode(lng,lat,precision=10,bits_per_char=6)Docstring:Encodealng/latpositionasageohashusingahilbertcurveThisfunctionencodesalng/latcoordinatetoageohashoflength`precision`onacorrespondingahilbertcurve.Eachcharacterencodes`bits_per_char`bitspercharacter(allowedare2,4and6bits[default6]).Hence,thegeohashencodesthelng/latcoordinateusing`precision`*`bits_per_char`bits.Thenumberofbitsdevidedby2givetheleveloftheusedhilbertcurve,e.g.precision=10,bits_per_char=6(defaultvalues)use60bitandalevel30hilbertcurvetomaptheglobe.Parameters:lng:floatLongitude;between-180.0and180.0;WGS84lat:floatLatitude;between-90.0and90.0;WGS84precision:intThenumberofcharactersinageohashbits_per_char:intThenumberofbitspercodingcharacterReturns:str:geohashforlng/latoflength`precision`File:.../geohash_hilbert/_hilbert.pyType:functionIn[7]:ghh.decode?Signature:ghh.decode(code,bits_per_char=6)Docstring:Decodeageohashonahilbertcurveasalng/latpositionDecodesthegeohash`code`asalng/latposition.Itassumes,thatthelengthof`code`correspondstotheprecision!Andthateachcharacterin`code`encodes`bits_per_char`bits.Donotmixgeohasheswithdifferent`bits_per_char`!Parameters:code:strThegeohashtodecode.bits_per_char:intThenumberofbitspercodingcharacterReturns:Tuple[float,float]:(lng,lat)coordinateforthegeohash.File:.../geohash_hilbert/_hilbert.pyType:functionIn[8]:ghh.decode_exactly?Signature:ghh.decode_exactly(code,bits_per_char=6)Docstring:Decodeageohashonahilbertcurveasalng/latpositionwitherror-marginsDecodesthegeohash`code`asalng/latpositionwitherror-margins.Itassumes,thatthelengthof`code`correspondstotheprecision!Andthateachcharacterin`code`encodes`bits_per_char`bits.Donotmixgeohasheswithdifferent`bits_per_char`!Parameters:code:strThegeohashtodecode.bits_per_char:intThenumberofbitspercodingcharacterReturns:Tuple[float,float,float,float]:(lng,lat,lng-error,lat-error)coordinateforthegeohash.File:.../geohash_hilbert/_hilbert.pyType:function
与原始geohash
这个包类似于geohash或geohash2包,因为它还提供了一种机制,可以将经纬度位置(wgs 84)编码(和解码)为一维geohash。但是,在前者使用z-order空间填充曲线的地方,这个包使用hilbert曲线。(此包的内核改编自wiki)。
note:参数(和返回)顺序从geohash
中的lat/lng更改为lng/lat。除此之外,此包是原始geohash
的替换品。
此外,字符串表示被改变(并且可修改)以补偿实现的特殊要求:geohash
使用修改的base32表示,即geohash中的每个字符编码5位。偶数位编码经度,奇数位编码纬度。每两个完整的位对z阶曲线的一个级别进行编码,例如,默认精度12使用12*5 = 60bit
对使用级别30的z阶曲线的一个经纬度位置进行编码。该实现还允许“半”级别,例如精度11使用11*5 = 55bit
对应于级别27.5的z阶曲线。
geohash表示详细信息
这个hilbert曲线的实现只允许完整的级别,因此我们有 支持base4(2bit)、base16(4bit)和自定义base64(默认为6bit) geohash表示。 按字典顺序排列,它们的整数值保持相同的顺序:
- base4:每个字符都在
'0123'
- base16:每个字符都在
'0123456789abcdef'
- base64:每个字符都在
'0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'
注意:不要混合来自原始geohash
和this的geohash,也不要混合base4、base16和base64 geohash表示。决定一个代表,然后坚持下去。
不同编码对实际编码精度和GeHHASH尺寸(赤道附近最大LNG/LAT误差)给出了更精细的晶粒控制:
lvl | bits | error | base4 | base16 | base64
-------------------------------------------------------------
0 | 0 | 20015.087 km | prec 0 | prec 0 | prec 0
1 | 2 | 10007.543 km | prec 1 | |
2 | 4 | 5003.772 km | prec 2 | prec 1 |
3 | 6 | 2501.886 km | prec 3 | | prec 1
4 | 8 | 1250.943 km | prec 4 | prec 2 |
5 | 10 | 625.471 km | prec 5 | |
6 | 12 | 312.736 km | prec 6 | prec 3 | prec 2
7 | 14 | 156.368 km | prec 7 | |
8 | 16 | 78.184 km | prec 8 | prec 4 |
9 | 18 | 39.092 km | prec 9 | | prec 3
10 | 20 | 19.546 km | prec 10 | prec 5 |
11 | 22 | 9772.992 m | prec 11 | |
12 | 24 | 4886.496 m | prec 12 | prec 6 | prec 4
13 | 26 | 2443.248 m | prec 13 | |
14 | 28 | 1221.624 m | prec 14 | prec 7 |
15 | 30 | 610.812 m | prec 15 | | prec 5
16 | 32 | 305.406 m | prec 16 | prec 8 |
17 | 34 | 152.703 m | prec 17 | |
18 | 36 | 76.351 m | prec 18 | prec 9 | prec 6
19 | 38 | 38.176 m | prec 19 | |
20 | 40 | 19.088 m | prec 20 | prec 10 |
21 | 42 | 954.394 cm | prec 21 | | prec 7
22 | 44 | 477.197 cm | prec 22 | prec 11 |
23 | 46 | 238.598 cm | prec 23 | |
24 | 48 | 119.299 cm | prec 24 | prec 12 | prec 8
25 | 50 | 59.650 cm | prec 25 | |
26 | 52 | 29.825 cm | prec 26 | prec 13 |
27 | 54 | 14.912 cm | prec 27 | | prec 9
28 | 56 | 7.456 cm | prec 28 | prec 14 |
29 | 58 | 3.728 cm | prec 29 | |
30 | 60 | 1.864 cm | prec 30 | prec 15 | prec 10
31 | 62 | 0.932 cm | prec 31 | |
32 | 64 | 0.466 cm | prec 32 | prec 16 |
-------------------------------------------------------------
其他功能
如果cython在安装期间可用,则cython内核扩展将被安装并用于64位或更低的geohash计算(mbp 2016、2.6 ghz英特尔酷睿i7、python 3.6.2、cython 0.26.1的计时):
In[1]:importgeohash_hilbertasghh# Without cython ...In[2]:ghh._hilbert.CYTHON_AVAILABLEOut[2]:FalseIn[3]:%timeitghh.encode(6.957036,50.941291,precision=10)39.4µs±614nsperloop(mean±std.dev.of7runs,10000loopseach)In[4]:%timeitghh.encode(6.957036,50.941291,precision=11)43.4µs±421nsperloop(mean±std.dev.of7runs,10000loopseach)
In[1]:importgeohash_hilbertasghh# With cython ...In[2]:ghh._hilbert.CYTHON_AVAILABLEOut[2]:True# almost 6x fasterIn[3]:%timeitghh.encode(6.957036,50.941291,precision=10)6.72µs±57.4nsperloop(mean±std.dev.of7runs,100000loopseach)# more than 64bit will be computed with pure python function.In[4]:%timeitghh.encode(6.957036,50.941291,precision=11)43.4µs±375nsperloop(mean±std.dev.of7runs,10000loopseach)
获取由geohash编码的实际矩形,即位置+-错误:
# returns a geojson Feature encoding the rectangle as a PolygonIn[9]:ghh.rectangle('Z7fe2G')Out[9]:{'bbox':(6.955718994140625,50.94085693359375,6.95709228515625,50.94154357910156),'geometry':{'coordinates':[[(6.955718994140625,50.94085693359375),(6.955718994140625,50.94154357910156),(6.95709228515625,50.94154357910156),(6.95709228515625,50.94085693359375),(6.955718994140625,50.94085693359375)]],'type':'Polygon'},'properties':{'bits_per_char':6,'code':'Z7fe2G','lat':50.941200256347656,'lat_err':0.00034332275390625,'lng':6.9564056396484375,'lng_err':0.0006866455078125},'type':'Feature'}
获取相邻的地理哈希:
In[10]:ghh.neighbours('Z7fe2G')Out[10]:{'east':'Z7fe2T','north':'Z7fe2H','north-east':'Z7fe2S','north-west':'Z7fe2I','south':'Z7fe2B','south-east':'Z7fe2A','south-west':'Z7fe2E','west':'Z7fe2F'}
绘制希尔伯特曲线:
# returns a geojson Feature encoding the Hilbert curve as a LineStringIn[11]:ghh.hilbert_curve(1)# this is a level 3 Hilbert curve:# 1 char * 6 bits/char = 6 bits => level 3Out[11]:{'geometry':{'coordinates':[(-157.5,-78.75),(-157.5,-56.25),(-112.5,-56.25),(-112.5,-78.75),(-67.5,-78.75),(-22.5,-78.75),(-22.5,-56.25),(-67.5,-56.25),(-67.5,-33.75),(-22.5,-33.75),(-22.5,-11.25),(-67.5,-11.25),(-112.5,-11.25),(-112.5,-33.75),(-157.5,-33.75),(-157.5,-11.25),(-157.5,11.25),(-112.5,11.25),(-112.5,33.75),(-157.5,33.75),(-157.5,56.25),(-157.5,78.75),(-112.5,78.75),(-112.5,56.25),(-67.5,56.25),(-67.5,78.75),(-22.5,78.75),(-22.5,56.25),(-22.5,33.75),(-67.5,33.75),(-67.5,11.25),(-22.5,11.25),(22.5,11.25),(67.5,11.25),(67.5,33.75),(22.5,33.75),(22.5,56.25),(22.5,78.75),(67.5,78.75),(67.5,56.25),(112.5,56.25),(112.5,78.75),(157.5,78.75),(157.5,56.25),(157.5,33.75),(112.5,33.75),(112.5,11.25),(157.5,11.25),(157.5,-11.25),(157.5,-33.75),(112.5,-33.75),(112.5,-11.25),(67.5,-11.25),(22.5,-11.25),(22.5,-33.75),(67.5,-33.75),(67.5,-56.25),(22.5,-56.25),(22.5,-78.75),(67.5,-78.75),(112.5,-78.75),(112.5,-56.25),(157.5,-56.25),(157.5,-78.75)],'type':'LineString'},'properties':{},'type':'Feature'}