在我们使用 Elastic Maps 时,经常会遇到 geohash。通常当我们描述一个位置的时候,我们很习惯使用经纬度来描述一个位置。在 Elasticsearch 中,有一个叫做 geo_point 的数据类型。例如,我们可以定义如下的一个索引:
PUT my-index-000001
{
"mappings": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
在上面,我们创建一个叫做 my-index-000001 的索引。在它的 mapping 中,我们定义了一个叫做 location 的字段。它的类型为 geo_point。针对 location,我们有各种各样的方式来对它写入,比如:
PUT my-index-000001/_doc/1
{
"text": "Geo-point as an object",
"location": {
"lat": 41.12,
"lon": -71.34
}
}
在上面,我们定义 location 为一个 object。我们也可以使用如下的方式来定义一个 geo_point:
PUT my-index-000001/_doc/2
{
"text": "Geo-point as a string",
"location": "41.42, -71.34"
}
在上面,我们使用一个字符串来定义 location。这里需要注意的是维度在前,经度在后。否则导入的数据会有错误。我们还可以使用如下的形式来定义:
PUT my-index-000001/_doc/3
{
"text": "Geo-point as an array",
"location": [-71.34, 41.12]
}
在上面,我们使用一个数组来定义 location。必须指出的是,在这种情况下,经度在前面,维度在后面。我们也可以使用如下的格式来定义:
PUT my-index-000001/_doc/4
{
"text": "Geo-point as a WKT POINT primitive",
"location": "POINT(-71.34 41.12)"
}
在上面,我们使用 POINT 来定义一个 location。
最后,我们甚至可以使用 geohash 来定义一个位置:
PUT my-index-000001/_doc/5
{
"text": "Geo-point as a geohash",
"location": "drm3btev3e86"
}
到这里,肯定有些开发者开始懵圈了。geohash 这到底是啥东东啊?我们可以打开网站 https://www.dcode.fr/geohash-coordinates。我们把上面的 geohash 代码输入到页面中,并求出相应的经纬度:
当然,我们也可以把经纬度信息写入,并求出相应的 geohash 代码:
显然这个 geohash 代表的就是我们上面所见到的(41.12,-71.34)经纬度坐标。
我们甚至可以到地址 https://www.movable-type.co.uk/scripts/geohash.html 输入我们的经纬度,并查出相应的位置信息:
那么 geohash 代码到底是怎么形成的呢?
Geohashing 是一种地理编码方法,用于将地理坐标(纬度和经度)编码为一小段数字和字母,以不同的分辨率在地图上划定一个区域(称为像元)。 字符串中的字符越多,位置越精确。Geohash 是 Gustavo Niemeyer在构建 geohash.org 时发明的系统,如下图所示:
地球分为32个矩形/单元。 每个单元格均由字母数字字符(其哈希)标识。 然后,可以将每个矩形(例如 d)进一步分为自己的32个矩形,生成 d0,d1,依此类推。 你几乎可以永远重复该过程,生成越来越小的矩形,而其相应的哈希值也越来越长。
Geohashes 使用 BASE-32 字母编码(字符可以是0到9和 A 到 Z,不包括 “A”,“I”,“L”和 “O”)。想象世界被划分成32个网格。一个 geohash 的第一个字符定义了它处于32个单元中的哪一个。该单元也将包含32个单元,以及这些的每一个单元将包含另外32个单元(等反复)。添加字符到 geohash 更加细分一个小单元,从而得到更加详细的位置信息。
精度因子决定了单元的大小。 例如,精度因子为1时将创建一个 5,000km 高和 5,000km宽 的单元,精度因子为6时将创建一个 0.61km 高和 1.22km 宽的单元,而精度因子为9时将创建 4.77m 高和 4.77m 宽(单元格并不总是正方形)。
好了,今天的文章介绍就到这里。希望你对 geohash 有一个比较深入的了解。我们可以利用 geohash 来对位置进行搜索。更多详细的信息,请参照 Elastic 官方文档 Geo grid aggregation 。