《大型综合项目-基于大数据平台的数据仓库》学习笔记(07):字典构建篇

本项目教程笔记源自多易教育《Titan综合数据仓库与数据运营系统》,在CSDN学院有相关视频教程购买链接,大数据企业级项目实战–Titan大型数据运营系统
本项目课程是一门极具综合性和完整性的大型大数据项目实战课程,课程项目的业务背景源自各类互联网公司对海量用户浏览行为数据和业务数据分析的需求及企业数据管理、数据运营需求。
学完本课程,你将很容易就拿到大数据数仓建设或用户画像建设等岗位的OFFER

本课程项目涵盖数据采集与预处理数据仓库体系建设、用户画像系统建设、数据治理(元数据管理、数据质量管理)、任务调度系统、数据服务层建设、OLAP即席分析系统建设等大量模块,力求原汁原味重现一个完备的企业级大型数据运营系统。

跟随项目课程,历经接近100+小时的时间,从需求分析开始,到数据埋点采集,到预处理程序代码编写,到数仓体系搭建…逐渐展开整个项目的宏大视图,构建起整个项目的摩天大厦。


一、地理位置字典构建

1、需求说明

在埋点日志中,有用户的地理位置信息,但是原始数据形式是GPS座标;
但是GPS座标在后续(地理位置维度分析)的分析中不好使用!
直接去匹配两个哪怕距离很近的gps座标,很可能都匹配不上!
gps座标的匹配,不应该做这种精确匹配,应该做范围匹配;

公司通过某渠道,收集到一批地理位置信息数据,只是数据格式需要加工:
在这里插入图片描述
加工的结果格式要求为:
GEOHASH码, 省,市,区
在这里插入图片描述
结果表数据,存放在HDFS即可(parquet格式);
具体实现方式不限!

2、新技能:GeoHash编码

在geo领域,gps座标,可以转化成一种编码:GeoHash编码(如wx3y),这种码有一个特点:

两个gps座标的位置越近,这两个座标的geohash码的相同的位数更多,只有更少的几位尾数不同!如下所示:
wx3y569
wx3y434

GeoHash编码的基本原理:
       不断地将地球的经度、纬度范围,进行二分,输出1/0比特,形成一串二进制码(二分的次数越多,输出的bit串越长)
在这里插入图片描述
然后将这一串二进制码,按照5bit一组合查base32码表,
在这里插入图片描述
输出最终结果!

geohash码的精确度对应表格:
在这里插入图片描述
gps座标 转码成 geohash编码,这个算法不需要自己手写,有现成的工具包

maven依赖座标:
<dependency>
    <groupId>ch.hsr</groupId>
    <artifactId>geohash</artifactId>
    <version>1.3.0</version>
</dependency>
api调用示例:
String geohashcode = GeoHash.withCharacterPrecision(45.667, 160.876547, 5).toBase32();
3、地理位置字典构建代码实现
1)、需求说明

“原料数据”是一种关系型表的层级结构
id 地点名称 父id 短名称 行政级别
在这里插入图片描述
实现方式有两种;

2)、实现方式

       (1)方式1
       在mysql上用sql语句查询来实现扁平化 ;
       将地理位置数据导入mysql,然后在mysql中形成扁平化结构的结果

SELECT
d.BD09_LNG,d.BD09_LAT,d.AREANAME,c.AREANAME,p.AREANAME
FROM t_md_areas d JOIN t_md_areas c on d.`LEVEL`=3 and d.PARENTID = c.ID
JOIN t_md_areas p on c.PARENTID = p.ID
;

       (2)方式2
              扁平化,也可以直接在sparksql中实现
              地理位置原始数据导入mysql,建表语句:

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for area
-- ----------------------------
DROP TABLE IF EXISTS `area`;
CREATE TABLE `area` (
  `lng` double DEFAULT NULL,
  `lat` double DEFAULT NULL,
  `province` mediumtext NOT NULL,
  `city` mediumtext NOT NULL,
  `district` mediumtext NOT NULL,
  `county` mediumtext NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

              查询sql语句:

create table area_dict
as
SELECT
a.BD09_LNG as lng,
a.BD09_LAT as lat,
a.AREANAME as district,
b.AREANAME as city,
c.AREANAME as province

from t_md_areas a 
join t_md_areas b  on a.`LEVEL`=3 and a.PARENTID=b.ID
join t_md_areas c  on b.PARENTID = c.ID

得到扁平化的表结构:
在这里插入图片描述
然后用spark去读mysql中的这个扁平化结果,并将其中的经纬度换成geohash码,输出保存即可

二、代码实现

package cn.doitedu.dw.dict

import java.util.Properties

import ch.hsr.geohash.GeoHash
import org.apache.spark.sql.SparkSession

object GeohashDict {

  def main(args: Array[String]): Unit = {


    // 构造spark
    val spark = SparkSession.builder()
      .appName(this.getClass.getSimpleName)
      .master("local[*]")
      .getOrCreate()
    import spark.implicits._


    // 读取mysql中的gps座标地理位置表
    val props = new Properties()
    props.setProperty("user","root")
    props.setProperty("password","root")

    val df = spark.read.jdbc("jdbc:mysql://localhost:3306/dicts","tmp",props)

    // 将gps座标通过geohash算法转成geohash编码
    val res = df.map(row=>{
      // 取出这一行的经、纬度
      val lng = row.getAs[Double]("BD09_LNG")
      val lat = row.getAs[Double]("BD09_LAT")
      val province = row.getAs[String]("province")
      val city = row.getAs[String]("city")
      val district = row.getAs[String]("district")

      // 调用geohash算法,得出geohash编码
      val geoCode = GeoHash.geoHashStringWithCharacterPrecision(lat,lng,5)


      // 组装返回结果
      (geoCode,province,city,district)
    }).toDF("geo","province","city","district")

    // 保存结果
    // res.show(10,false)
    res.write.parquet("data/dict/geo_dict/output")

    spark.close()

  }
}

三、地理字典加强补充–高德服务

从日志数据处理中,挑出那些查不到省市区的gps座标,专门存在一个目录中
然后,隔一段时间,做一次如下的事情,来充实我们自己的地理位置字典数据:
val df = spark.read.parquet("那些查不到省市区的座标数据文件")
df.map(row=>{
val lng =  row.getAs[Double]("lng")
      val lat  = row.getAs[Double]("lat")
val response = httpClient.get("高德的服务api地址,apikey,lng,lat")
val province = JSON.get(.....)
val city = JSON.get(....)
val district = JSON.get(.....)

val geo = GeoHash.geoStringWithCharacterPrecesion(lat,lng,5)
(geo,province,city,district)
}
)

本项目教程笔记源自多易教育《Titan综合数据仓库与数据运营系统》,在CSDN学院有相关视频教程购买链接,大数据企业级项目实战–Titan大型数据运营系统
本项目课程是一门极具综合性和完整性的大型大数据项目实战课程,课程项目的业务背景源自各类互联网公司对海量用户浏览行为数据和业务数据分析的需求及企业数据管理、数据运营需求。
学完本课程,你将很容易就拿到大数据数仓建设或用户画像建设等岗位的OFFER

本课程项目涵盖数据采集与预处理数据仓库体系建设、用户画像系统建设、数据治理(元数据管理、数据质量管理)、任务调度系统、数据服务层建设、OLAP即席分析系统建设等大量模块,力求原汁原味重现一个完备的企业级大型数据运营系统。

跟随项目课程,历经接近100+小时的时间,从需求分析开始,到数据埋点采集,到预处理程序代码编写,到数仓体系搭建…逐渐展开整个项目的宏大视图,构建起整个项目的摩天大厦。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章