項目說明:附件爲要計算數據的demo。點擊打開鏈接
其中bs_log文件夾數據格式爲(手機號,時間戳,基站ID,連接狀態(“1”爲連接,“0”爲斷開))
lac_info.txt 文件數據格式爲(基站ID,經度,緯度,信號輻射類型)
程序思路:
1, 先根據"手機號,基站ID"構成一個元祖,做爲唯一標識, 和時間戳構成新的數據結構->(手機號, 站點, 時間戳)
2、(手機號,基站ID)作爲key,通過reduceByKey算子進行聚合,計算出在基站的停留時間,構成新的數據結構,以便和座標數據進行join,->(基站ID,(手機號,停留時間))
3、將基站座標數據信息通過map,構建成數據類型 ->(基站ID,(經度,緯度))
4、將2、3進行join操作,構成新的數據類型 ->(手機號,基站ID,停留時間,經度,緯度)
5、按手機號進行分組。->(手機號,(手機號,基站ID,停留時間,經度,緯度))
6、取出停留時間最長的兩個基站ID。
具體程序如下:
package cn.allengao.Location
import org.apache.spark.{SparkConf, SparkContext}
/**
* class_name:
* package:
* describe: 基站信息查詢
* creat_user: Allen Gao
* creat_date: 2018/1/29
* creat_time: 10:03
**/
/*
* 說明:
* 1, 先根據"手機號,基站ID"構成一個元祖,做爲唯一標識, 和時間戳構成新的數據結構->(手機號, 站點, 時間戳)
* 2、(手機號,基站ID)作爲key,通過reduceByKey算子進行聚合,計算出在基站的停留時間,構成新的數據結構,
* 以便和座標數據進行join,->(基站ID,(手機號,停留時間))
* 3、將基站座標數據信息通過map,構建成數據類型 ->(基站ID,(經度,緯度))
* 4、將2、3進行join操作,構成新的數據類型 ->(手機號,基站ID,停留時間,經度,緯度)
* 5、按手機號進行分組。->(手機號,(手機號,基站ID,停留時間,經度,緯度))
* 6、取出停留時間最長的兩個基站ID。
*
*/
object UserLocation {
def main(args: Array[String]): Unit = {
//創建Spark配置信息
val conf = new SparkConf().setAppName("UserLocation").setMaster("local[*]")
//建立Spark上下文,並將配置信息導入
val sc = new SparkContext(conf)
/*
基站連接手機號,連接時間戳,基站站點ID信息,“1”表示連接,“0”表示斷開連接。
18688888888,20160327082400,16030401EAFB68F1E3CDF819735E1C66,1
*/
//從log文件拿到數據,並按行採集。
//sc.textFile("c://information//bs_log").map(_.split(",")).map(x => (x(0), x(1), x(2), x(3)))
val rdd_Info = sc.textFile("j://information//bs_log").map(line => {
//通過“,”將數據進行切分field(0)手機號,field(1)時間戳,field(2)基站ID信息,field(3)事件類型
val fields = line.split(",")
//事件類型,“1”表示連接,“0”表示斷開。
val eventType = fields(3)
val time = fields(1)
//連接基站將時間戳至爲“-”,斷開基站將時間戳至爲“+”,以便後面進行計算。
val timeLong = if(eventType == "1") -time.toLong else time.toLong
//構成一個數據類型(手機號,基站ID信息,帶符號的時間戳)
((fields(0),fields(2)),timeLong)
})
val rdd_lacInfo = rdd_Info.reduceByKey(_+_).map(t=>{
val mobile = t._1._1
val lac = t._1._2
val time = t._2
(lac, (mobile, time))
})
val rdd_coordinate = sc.textFile("j://information//lac_info.txt").map(line =>{
val f = line.split(",")
//(基站ID, (經度, 緯度))
(f(0),(f(1), f(2)))
})
//rdd1.join(rdd2)-->(CC0710CC94ECC657A8561DE549D940E0,((18688888888,1300),(116.303955,40.041935)))
val rdd_all = rdd_lacInfo.join(rdd_coordinate).map(t =>{
val lac = t._1
val mobile = t._2._1._1
val time = t._2._1._2
val x = t._2._2._1
val y = t._2._2._2
(mobile, lac, time, x, y)
})
//按照手機號進行分組
val rdd_mobile = rdd_all.groupBy(_._1)
//取出停留時間最長的前兩個基站
val rdd_topTwo= rdd_mobile.mapValues(it =>{
it.toList.sortBy(_._3).reverse.take(2)
})
// println(rdd_Info.collect().toBuffer)
// println(rdd_lacInfo.collect().toBuffer)
// println(rdd_coordinate.collect().toBuffer)
// println(rdd_all.collect().toBuffer)
// println(rdd_mobile.collect().toBuffer)
// println(rdd_topTwo.collect().toBuffer)
rdd_topTwo.saveAsTextFile("j://information//out")
sc.stop()
}
}