基于Idea的Spark大数据分析--scala

问题重述

• 基于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


1.解题原理

输出A:

以第一列统计车辆数,去重

输出B:

1.从(district.txt)文件中取第一个区的记录,获得其名称D1、中心坐标M(x0,y0)和半径r;

2.从(taxi_gps.txt)中获取第一条位置点记录,获得其坐标N(x1,y1)

3.利用欧几里得距离计算公式计算点M和N的距离dis,如果dis<r,则认为该位置记录属于区域D1;得到<D1,1>

4.继续从2开始循环,获得第二个位置记录;直至所有记录遍历完。

5.继续从1开始循环,获得第二个区的记录




2.数据说明

待统计区域中心数据格式

区域名称:北京城区拼音,例: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=有效

结束串:回车符+换行符




3.实验步骤


1 . 搭建hadoop

1.1 安装jdk

在这里插入图片描述

1.2安装部署伪分布式hadoop集群

在这里插入图片描述
在这里插入图片描述

安装测试成功


2.搭建spark

2.1 安装spark
在这里插入图片描述

2.2 安装scala与Idea编译器

2.2.1 安装scala
在这里插入图片描述

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()
  }
}


最终结果为:
在这里插入图片描述

  • 20
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值