GeoHash编码原理和代码演示
程序员文章站
2024-03-15 14:23:41
...
GeoHash编码原理和代码演示
1. 背景
1.1 概述
- 在大数据领域中,时常需要进行海量数据的映射检索,其中GPS转换为地理位置以及IP地址转换为地理位置就是一种很常见需求。
- 由于数据量很大,如何进行快速查询就需要使用到各种算法。
- 在大数据领域,常见的快速匹配如布隆过滤器,bitmap算法,hyperloglog算法这些是位图算法。
- 今天要说的geohash算法,则是二分法结合编码的一种地理位置信息算法。
1.2 原理
- 经度范围是东经180到西经180,纬度范围是南纬90到北纬90,我们设定西经为负,南纬为负,所以地球上的经度范围就是[-180, 180],纬度范围就是[-90,90]。如果以本初子午线、赤道为界,地球可以分成4个部分
- 纬度范围[-90°, 0°)用二进制0代表,(0°, 90°]用二进制1代表,经度范围[-180°, 0°)用二进制0代表,(0°, 180°]用二进制1代表,那么地球可以分成如下4个部分
- 更小范围二分划分
- 转换计算方法步骤
- 将经纬度变成二进制。
- 将经纬度合并
- 按照Base32进行编码
参考自:https://www.jianshu.com/p/2fd0cf12e5ba
2. 案例
- 环境
- idea 2020
- jdk 1.8
- maven 3.6.3
- pom文件
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.11</artifactId>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-hive_2.11</artifactId>
</dependency>
<dependency>
<groupId>ch.hsr</groupId>
<artifactId>geohash</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>1.7.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 把依赖jar中的用到的类,提取到自己的jar中 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<mainClass></mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<!--下面是为了使用 mvn package命令,如果不加则使用mvn assembly-->
<executions>
<execution>
<id>make-assemble</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
- 代码
object GeoHashDict {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder()
.config("spark.sql.shuffle.partitions","2")
.appName("地理位置知识库加工")
.master("local")
.getOrCreate()
import spark.implicits._
import org.apache.spark.sql.functions._
// 加载mysql中的原始表数据,里面包含省市区和经纬度信息
val props = new Properties()
props.load(GeoHashDict.getClass.getClassLoader.getResourceAsStream("db.properties"))
val df = spark.read.jdbc("jdbc:mysql://localhost:3306/realtimedw?useUnicode=true&characterEncoding=utf8","t_md_areas",props)
// 扁平化操作
df.createTempView("df")
val df2 = spark.sql(
"""
|
|select
|province.areaname as province,
|city.areaname as city,
|region.areaname as region,
|region.bd09_lng as lng,
|region.bd09_lat as lat
|
|from df region join df city on region.parentid = city.id and region.level=3
| join df province on city.parentid=province.id
|""".stripMargin)
df2.show(20,false)
// 自定义函数
val gps2geo: UserDefinedFunction = udf((lat:Double, lng:Double)=>{
// 5是geohash精度,越长,地理位置精度越高
GeoHash.geoHashStringWithCharacterPrecision(lat,lng,5)
})
val res = df2.select('province,'city,'region,gps2geo('lat,'lng) as "geohash")
res.write.parquet("dataware/data/geodict")
spark.close()
}
}
- 注意使用的maven中jar包是这个
推荐阅读
-
GeoHash编码原理和代码演示
-
分享PHP代码 UTF-8和Unicode编码互转(多语言) 博客分类: PHP技术 php编码functionUTF-8Unicode
-
SpringMVC入门教程及其原理讲解和实例代码下载 博客分类: javaspring SpringMVC入门教程原理讲解实例代码
-
Asp.Net中的字符串和HTML十进制编码转换实现代码
-
Asp.Net中的字符串和HTML十进制编码转换实现代码
-
c# Base64编码和图片的互相转换代码
-
Spring-boot原理及spring-boot-starter实例和代码
-
PHP实现采集程序原理和简单示例代码_php实例
-
android开发之蜂鸣提示音和震动提示的实现原理与参考代码
-
php实现utf-8和GB2312编码相互转换函数代码_PHP