• 基于Eclipse或IDEA完成Spark大数据分析
• Spark1.x或2.x版本均可
• 能够读取给定的数据文件
• 出租车GPS数据文件(taxi_gps.txt)
• 北京区域中心坐标及半径数据文件(district.txt)
• 能够输出以下统计信息
• A:该出租车GPS数据文件(taxi_gps.txt)包含多少量车?
• B:北京每个城区的车辆位置点数(每辆车有多个位置点,允许重复)
开发环境:
Spark版本 spark-2.1.1-bin-hadoop2.7
Scala版本 Scala-2.11.11
输出A:
以第一列统计车辆数,去重
输出B:
1.从(district.txt)文件中取第一个区的记录,获得其名称D1、中心坐标M(x0,y0)和半径r;
2.从(taxi_gps.txt)中获取第一条位置点记录,获得其坐标N(x1,y1)
3.利用欧几里得距离计算公式计算点M和N的距离dis,如果dis
4.继续从2开始循环,获得第二个位置记录;直至所有记录遍历完。
5.继续从1开始循环,获得第二个区的记录
待统计区域中心数据格式
区域名称:北京城区拼音,例:haidianqu, chaoyangqu, dongchengqu
区域中心GPS经度:格式ddd.ddddddd,以度为单位。
区域中心GPS纬度:格式dd.ddddddd,以度为单位。
区域半径:格式dd,以km为单位
出租车GPS数据格式说明
数据以ASCII文本表示,以逗号为分隔符,以回车换行符(0x0D 0x0A)结尾。数据项及顺序:车辆标识、触发事件、运营状态、GPS时间、GPS经度、GPS纬度,、GPS速度、GPS方向、GPS状态
车辆标识:6个字符
触发事件:0=变空车,1=变载客,2=设防,3=撤防,4=其它
运营状态:0=空车,1=载客,2=驻车,3=停运,4=其它
GPS时间:格式yyyymmddhhnnss,北京时间
GPS经度:格式ddd.ddddddd,以度为单位。
GPS纬度:格式dd.ddddddd,以度为单位。
GPS速度:格式ddd,取值000-255内整数,以公里/小时为单位。
GPS方位:格式ddd,取值000-360内整数,以度为单位。
GPS状态:0=无效,1=有效
结束串:回车符+换行符
1 . 搭建hadoop
1.1 安装jdk
1.2安装部署伪分布式hadoop集群
安装测试成功
2.搭建spark
2.2 安装scala与Idea编译器
2.2.2 安装IDEA并配置环境
nohup ./idea.sh & #后台启动 idea
3.解题
3.1 第一题解题
以第一列统计车辆数并去重:
package org.haerxiluo.lab
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql._
object TaxiNumCount{
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
conf.setAppName("TaxiNumCount")
conf.setMaster("local[*]")
conf.set("spark.testing.memory", "2147480000")
val sc = new SparkContext(conf)
sc.setLogLevel("ERROR") //减少日志输出
val data = sc.textFile("./taxi_gps.txt").flatMap(_.split("\n"))
.map{line => line.split(",")(0)
}.distinct().collect() // 读取并去重处理
println(data.length)
sc.stop()
}
}
结果如下:
3.2 第二题解题
由经纬度计算两点距离测试公式代码:
object longitude {
private val EARTH_RADIUS = 6378.137
private def rad(d: Double) = d * Math.PI / 180.0
def GetDistance(lat1: Double, lng1: Double, lat2: Double, lng2: Double): Double = {
val radLat1 = rad(lat1)
val radLat2 = rad(lat2)
val a = radLat1 - radLat2
val b = rad(lng1) - rad(lng2)
var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)))
s = s * EARTH_RADIUS
s = s * 10000.round / 10000
s
}
def main(args: Array[String]): Unit = {
val res = GetDistance(116.452437, 39.941809, 116.6999512, 39.9006233)
System.out.println(res)
}
}
第二题完整代码:
package org.haerxiluo.lab
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
import scala.collection.mutable.Map
import scala.math._
object TaxiGps {
//使用样例类读取district数据
case class District(var name: String,latitude: Double, longitude: Double, radius: Double)
val EARTH_RADIUS = 6378.137
def rad(d: Double) = d * Math.PI / 180.0 //度转换公式
// 计算两点间距离
def GetDistance(lat1: Double, lng1: Double, lat2: Double, lng2: Double): Double = {
val radLat1 = rad(lat1)
val radLat2 = rad(lat2)
val a = radLat1 - radLat2
val b = rad(lng1) - rad(lng2)
var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)))
s = s * EARTH_RADIUS
s = s * 10000.round / 10000
s
}
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
conf.setAppName("TaxiGPS")
conf.setMaster("local[*]")
conf.set("spark.testing.memory", "2147480000")
val sc = new SparkContext(conf)
sc.setLogLevel("ERROR")
val data2 = sc.textFile("./district.txt").map(line => line.split(","))
.map(arr => District(arr(0), arr(1).toDouble, arr(2).toDouble, arr(3).toDouble)).collect()
// val data1 = sc.textFile("./district.txt").flatMap(_.split("\n"))
// .map{line => (line.split(",")(0),line.split(",")(1).toDouble,line.split(",")(2).toDouble,line.split(",")(3).toDouble)}.collect()
//
//
// println(data1(0)._1)
println(data2(1))
val data3 = sc.textFile("./taxi_gps.txt").flatMap(_.split("\n"))
.map { line => (line.split(",")(4).toDouble, line.split(",")(5).toDouble)
}.collect()
// println(data3(20199)._1)
// val res = GetDistance(data2(0).latitude,data2(0).longitude,data3(0)._1,data3(0)._2)
// println(res)
var count = 0
var count1 = 0
var count2 = 0
var count3 = 0
var count4 = 0
var count5 = 0
var count6 = 0
var count7 = 0
for (i <- 0 to 6) {
for (j <- 0 to 20199) {
val res = GetDistance(data2(i).latitude, data2(i).longitude, data3(j)._1, data3(j)._2)
// println(res)
if (res < data2(i).radius) {
count += 1
val tuple2: (String, Int) = (s"D$i", count)
// println(tuple2._1 + "," + tuple2._2)
if(tuple2._1 == "D0") count1 += 1
if(tuple2._1 == "D1") count2 += 1
if(tuple2._1 == "D2") count3 += 1
if(tuple2._1 == "D3") count4 += 1
if(tuple2._1 == "D4") count5 += 1
if(tuple2._1 == "D5") count6 += 1
if(tuple2._1 == "D6") count7 += 1
}
}
}
val arr = Array(count1,count2,count3,count4,count5,count6,count7)
for(i <- 0 to 6){
println(s"D$i:"+arr(i))
}
sc.stop()
}
}