《大型綜合項目-基於大數據平臺的數據倉庫》學習筆記(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+小時的時間,從需求分析開始,到數據埋點採集,到預處理程序代碼編寫,到數倉體系搭建…逐漸展開整個項目的宏大視圖,構建起整個項目的摩天大廈。

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