今天介紹一個座標轉換的udf,包括java代碼的編寫的udf函數的創建
1. 編寫Java代碼
- 打開IDEA,創建項目,導入pom文件,見下面,在Java目錄下創建udf的包,編寫GPSConverter類
<properties>
<hadoop.version>2.6.0-cdh5.13.1</hadoop.version>
<hive.version>1.1.0-cdh5.13.1</hive.version>
</properties>
<!-- 因爲使用CDH的hadoop和hive,因此要添加CDH的官方repository,才能夠下載相應的依賴包 -->
<!-- 如果使用Apache版本的hadoop和hive,則不需要添加該repository -->
<repositories>
<repository>
<id>cloudera</id>
<url>http://repository.cloudera.com/artifactory/cloudera-repos</url>
</repository>
</repositories>
<dependencies>
<!-- 添加依賴組件,根據上方配置的版本參數和repository知識庫下載依賴 -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>${hive.version}</version>
</dependency>
<!-- junit是java的單元測試框架 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
- 接下來編寫GPSConverter的代碼,代碼共有2個方法,分別是udf執行調用的方法、座標轉換的方法。接下來見代碼
package udf;
/**
* Copyright (C), 2015-2019, XXX有限公司
* FileName: GPSConverte
* Date: 2019/7/15 18:04
* Description: 百度座標轉化爲火星座標的UDF
* History:
* <author> <time> <version> <desc>
* shipengfei 版本號 描述
*/
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;
@Description(name = "座標處理函數",
value = "輸入兩個double類型的值,輸出double數組 輸入的是百度座標系,輸出的是火星座標系")
/**
* 〈一句話功能簡述〉<br>
* 〈百度座標轉化爲火星座標的UDF〉
*
* @author 72038714
* @create 2019/7/15
* @since 1.0.0
*/
public class GPSConverter extends UDF {
public static final String BAIDU_LBS_TYPE = "bd09ll";
public static double pi = 3.1415926535897932384626;
public static double a = 6378245.0;
public static double ee = 0.00669342162296594323;
public String evaluate (Double url,Double flag){
String gcj02 = bd09_To_Gcj02(url, flag);
return gcj02;
// return bd09_To_Gcj02(url, flag);
}
/**
* * 火星座標系 (GCJ-02) 與百度座標系 (BD-09) 的轉換算法 * * 將 BD-09 座標轉換成GCJ-02 座標 * * @param
* bd_lat * @param bd_lon * @return
*/
public static String bd09_To_Gcj02(double bd_lat, double bd_lon) {
double x = bd_lon - 0.0065, y = bd_lat - 0.006;
double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * pi);
double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * pi);
double gg_lon = z * Math.cos(theta);
double gg_lat = z * Math.sin(theta);
return gg_lat+"|"+gg_lon;
}
//測試函數
public static void main(String[] args) {
String s = bd09_To_Gcj02(109.5648, 23.5468);
System.out.println(s);
}
}
2. 打包.jar文件
-
在測試座標轉換沒有問題之後,開始對代碼進行打包,因爲現在的pom依賴中的包在hadoop集羣都有,所以我們只要打包自己寫的代碼就可以
-
點擊+之後,第一行出現JAR的信息,點擊,再點擊From Modules with denpendencies信息,會彈出下面的窗口
-
添加剛纔編寫的主類
-
添加完成後會出現下面的窗口,這裏主要是選擇打包後的jar文件的路徑和需要打包的信息,因爲在hadoop中都有我們剛纔添加的依賴,所以我們只要打包剛纔常見的項目的包positionUDF,按住shift鍵,可以快速選中不需要的依賴,右鍵remove掉
-
remove之後,就只剩下我們剛纔創建的項目了,選擇Apply,到這裏,我們打包的設置完成,接下來進行實際打包操作。
-
實際打包操作,點擊Build之後,選擇Build Artifacts,會彈出一個小窗口,會顯示剛纔我們創建的項目,點擊Build,就會進行打包,右下角有藍色的進度條。我們在因爲截圖是窗口會消失,這裏就不截屏了
-
打包完成後,在項目的目錄下會多出一個out目錄,我們打包的jar文件就放在這個位置,也可以在我們剛纔設置的目錄上找到對應的jar文件,我打包後的文件大小2.97k,如果文件大小超過1M,說明在打包設置的時候,我們添加進來了其他依賴。
到這裏我們的jar文件編寫打包都完成了,下面就是在集羣上創建udf的步驟
3.創建UDF函數
創建udf的步驟是 將jar文件先發送到集羣上,然後添加jar文件,然後創建函數,最終測試執行。
- 將剛纔的jar文件上傳到linux文件系統的任意目錄
找一個對應的hadoop目錄我這裏是hdfs://nameservice/hive/warehouse/test.db/tmp_ss這個目錄
使用命令將文件上傳
//上傳文件的命令
hadoop fs -put -f positionUDF.jar hdfs://nameservice/hive/warehouse/test.db/tmp_ss
- 添加jar 文件 打開hive,執行add jar hdfs://nameservice/hive/warehouse/test.db/tmp_ss/positionUDF.jar;命令,進行文件添加,這裏可以換到自己設置的目錄上。
- 創建udf函數,執行的命令是
//temporary 這個關鍵字表示創建臨時函數,也可以不寫,創建永久函數,需要自行百度解決
create temporary temporary *** as '類目錄'
這裏執行的命令是
create temporary temporary gps_con as 'udf.GPSConverter';
我這裏創建函數和測試函數的顯示,在evaluate 這個方法中,將參數傳入反了,代碼上面已經修改,我的處理是將結果拼接爲string類字符串,這裏大家可以根據要求輸出改變數據類型爲double類型數組,也可以在hive中使用split函數處理。
本次就介紹到這裏,歡迎大家關注,有問題也可以評論留言!