开发环境搭建
创建项目
前文说过的基础软件比如 java scala等等都先安装好再继续
1: 打开Idea,新建项目,选择Maven下一步
2: 填写名称,完成即可
3: 打开Pom 文件先把提前定义好的属性加进去
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<gt.version>23.0</gt.version>
<geomesa.version>3.0.0</geomesa.version>
<scala.abi.version>2.11</scala.abi.version>
<scala.version>2.11.7</scala.version>
<kryo.version>4.0.2</kryo.version>
<spark.version>2.4.3</spark.version>
</properties>
如果版本发生变化了,自己看着改
再把Geotools的仓库加进去,geotools以前的仓库是不能用的了
<repositories>
<repository>
<id>aliyun</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
<repository>
<id>GeoSolutions</id>
<url>https://repo.osgeo.org/repository/release/</url>
</repository>
</repositories>
添加依赖,这里的依赖很多,也没有仔细整理,很有重复依赖,Geomesa底层的包依赖的三方包有时候他们排除了,
有时候没排除,懒得花时间整理,就先全部加进来
<dependencies>
<dependency>
<groupId>org.locationtech.geomesa</groupId>
<artifactId>geomesa-spark-core_2.11</artifactId>
<version>${geomesa.version}</version>
</dependency>
<!--geomesa Geotools数据源包-->
<dependency>
<groupId>org.locationtech.geomesa</groupId>
<artifactId>geomesa-gt-spark_2.11</artifactId>
<version>${geomesa.version}</version>
</dependency>
<!--spark环境-->
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>${spark.version}</version>
</dependency>
<!--kryo序列化包,Geomesa底层引用了,但是打包排除了,需要重新引用-->
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
<version>${kryo.version}</version>
</dependency>
<!--geotools的一揽子包-->
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-wkt</artifactId>
<version>${gt.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-wkt</artifactId>
<version>${gt.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-hsql</artifactId>
<version>${gt.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-opengis</artifactId>
<version>${gt.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-main</artifactId>
<version>${gt.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
如果遇到某些插件下载不下来,就先去仓库下面把对应的文件夹删掉,重新刷新pom
4:设置Scala开发包
在项目上右键,选择Add Frameword Support选项,在最下面找到Scala选项,选择当前版本 确定,
如果没有就Create选择一下Scala安装目录,添加进来就可以
5:创建Scala OBject文件,在包目录上右键 选择Scala Calss选项,选择Object类型,输入对象名就可以了
加载ShpFile文件
新建一个Scala class LoadShpFileRdd,具体代码如下
package hello.geomesa.shp
import java.io.File
import org.apache.hadoop.conf.Configuration
import org.apache.spark.{SparkConf, SparkContext, TaskContext}
import org.geotools.data.Query
import org.locationtech.geomesa.spark.{GeoMesaSpark, GeoMesaSparkKryoRegistrator}
import scala.collection.JavaConversions._
object LoadShpFileRdd {
def main(args: Array[String]): Unit = {
var startTime = System.currentTimeMillis();
val sparkConf = new SparkConf().setMaster("local[6]").setAppName("LoadShpFileRdd"); //默认启动6个进程,默认也就是6个分区
sparkConf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer") //序列化方式一定要设置,geomesa不支持默认的序列化,只支持这一种
sparkConf.set("spark.kryo.registrator", classOf[GeoMesaSparkKryoRegistrator].getName)
val sparkContext = SparkContext.getOrCreate(sparkConf);
val path = "D:\\work\\bigdata\\data\\TDLYXZ\\TDLYXZ.shp";
var params: Map[String, String] = Map()
var File = new File(path)
params += ("url" -> File.toURI.toURL.toString) //其他参数跟geotools的设置一模一样
params += ("charset" -> "UTF-8")
params += ("geotools" -> "true") //设置数据源为Geotools
val typName = "TDLYXZ"
val query = new Query(typName)
var spatialRDD = GeoMesaSpark(params).rdd(new Configuration(), sparkContext, params, query)
//遍历所有数据分区,并且打印数据
spatialRDD.foreachPartition(partition => {
//因为partition是以流的方式获取数据,且数据流只流一次,在这里不要使用partition的count或者其他统计函数,否则下面的foreach是没有数据的
println("分区".concat(TaskContext.getPartitionId.toString))
partition.foreach(item => {
println(item)
})
})
val endTime = System.currentTimeMillis
println((endTime - startTime) / 1000)
}
}
上面就是一个完整例子,加载本地shp文件,且打印所有的分区数据,一个shp文件默认分区数量是跟设置的任务数量一致。
设置了6个任务,数据也就会被分别加载到6个数据分区中,
Spark我是个外行,基本等于不会,这里只能尽量实现功能,代码好看不好看,结构好不好,不要计较
其他的数据源如Hbase fs等的连接方式参考官网
https://www.geomesa.org/documentation/stable/user/spark/providers.html