数据分析中,我们经常遇到经纬度相关的GIS处理,但Hive本身并不支持,我们可以通过自定义实现UDF函数的方法进行实现。
源码下载
https://github.com/Angryshark128/gisutilforhive.git
类包下载
链接:https://pan.baidu.com/s/19-bZz9ttX-RW6-7nNiBGPw
提取码:ap99
实现步骤
- 代码实现
- 打包上传
- 注册测试
代码实现
核心代码
实现在GisUtil.java中
public class GisUtil {
public static Double pi = Math.PI;
public static Double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
public static Double a = 6378245.0;
public static Double ee = 0.00669342162296594323;
static double longRadius = 6378137.00;
static double shortRadius = 6356752.3142;
public static void main(String[] args) {
String coords = "[[[116.394461, 39.973096 ], [116.388437, 39.973076 ], [116.386609, 39.972803 ], [116.384851, 39.972951 ], [116.381435, 39.972796 ], [116.381829, 39.972084 ], [116.381111, 39.970135 ], [116.380709, 39.967835 ], [116.370521, 39.967529 ], [116.370593, 39.965598 ], [116.372211, 39.949098 ], [116.368539, 39.948289 ], [116.367257, 39.947582 ], [116.365259, 39.946766 ], [116.357113, 39.944465 ], [116.356525, 39.944976 ], [116.356553, 39.948078 ], [116.356763, 39.948128 ], [116.356893, 39.950026 ], [116.356307, 39.951385 ], [116.355653, 39.951688 ], [116.355161, 39.95166 ], [116.351537, 39.950508 ], [116.350997, 39.947036 ], [116.351957, 39.943969 ], [116.350341, 39.942991 ], [116.346799, 39.943646 ], [116.342051, 39.943154 ], [116.340265, 39.943242 ], [116.338319, 39.942905 ], [116.335817, 39.943179 ], [116.334845, 39.943517 ], [116.334119, 39.943452 ], [116.333325, 39.943979 ], [116.332729, 39.944121 ], [116.332119, 39.944039 ], [116.331407, 39.943572 ], [116.328471, 39.942655 ], [116.329149, 39.94134 ], [116.329555, 39.940025 ], [116.330255, 39.939911 ], [116.331123, 39.938923 ], [116.333287, 39.938263 ], [116.334577, 39.925845 ], [116.335093, 39.922982 ], [116.334889, 39.922657 ], [116.334791, 39.912451 ], [116.334881, 39.911647 ], [116.335587, 39.909509 ], [116.335725, 39.908178 ], [116.335649, 39.90712 ], [116.334985, 39.90708 ], [116.334749, 39.905055 ], [116.335061, 39.9042 ], [116.335825, 39.903507 ], [116.335279, 39.903082 ], [116.335543, 39.902798 ], [116.335119, 39.902592 ], [116.335155, 39.898513 ], [116.338057, 39.898523 ], [116.338273, 39.897933 ], [116.338287, 39.897081 ], [116.331407, 39.896736 ], [116.325961, 39.896784 ], [116.326009, 39.89432 ], [116.325467, 39.894053 ], [116.325387, 39.893867 ], [116.325541, 39.893598 ], [116.326177, 39.893295 ], [116.326105, 39.890982 ], [116.326587, 39.890256 ], [116.326627, 39.889665 ], [116.324501, 39.88959 ], [116.324561, 39.887644 ], [116.323803, 39.887513 ], [116.323837, 39.884767 ], [116.323347, 39.884426 ], [116.323201, 39.883985 ], [116.321961, 39.883679 ], [116.321849, 39.881972 ], [116.322415, 39.881793 ], [116.322227, 39.881544 ], [116.321417, 39.881537 ], [116.321411, 39.875305 ], [116.323569, 39.876183 ], [116.324941, 39.876298 ], [116.329333, 39.876038 ], [116.332787, 39.875467 ], [116.341613, 39.876139 ], [116.342641, 39.87609 ], [116.343543, 39.875714 ], [116.344299, 39.875074 ], [116.344615, 39.873751 ], [116.346933, 39.873753 ], [116.347179, 39.873865 ], [116.347395, 39.873569 ], [116.349601, 39.873635 ], [116.349305, 39.870339 ], [116.349577, 39.869804 ], [116.350279, 39.869185 ], [116.351425, 39.868968 ], [116.381169, 39.871154 ], [116.399585, 39.872199 ], [116.399181, 39.880155 ], [116.398761, 39.880785 ], [116.398749, 39.883549 ], [116.397921, 39.89871 ], [116.396399, 39.899192 ], [116.395895, 39.899851 ], [116.395509, 39.907695 ], [116.392585, 39.907567 ], [116.392561, 39.908266 ], [116.392807, 39.908439 ], [116.392873, 39.908709 ], [116.392819, 39.91075 ], [116.391843, 39.910771 ], [116.391727, 39.912411 ], [116.392213, 39.912438 ], [116.392197, 39.913003 ], [116.392369, 39.913243 ], [116.391915, 39.922705 ], [116.396895, 39.922886 ], [116.396915, 39.923327 ], [116.399881, 39.923432 ], [116.399571, 39.928489 ], [116.396755, 39.928423 ], [116.395999, 39.940341 ], [116.395399, 39.94065 ], [116.394247, 39.940762 ], [116.393705, 39.957115 ], [116.386777, 39.956796 ], [116.387613, 39.96089 ], [116.387913, 39.961095 ], [116.388173, 39.963032 ], [116.389287, 39.963193 ], [116.389493, 39.963418 ], [116.388799, 39.963517 ], [116.388745, 39.964532 ], [116.388247, 39.96453 ], [116.388301, 39.965824 ], [116.390507, 39.966223 ], [116.390301, 39.968124 ], [116.391633, 39.96816 ], [116.391701, 39.968682 ], [116.392925, 39.969122 ], [116.394077, 39.969241 ], [116.394601, 39.969509 ], [116.394841, 39.970097 ], [116.394769, 39.973121 ], [116.394461, 39.973096 ] ] ]";
System.out.println(convert2Wkt("POLYGON", coords));
System.out.println(getDistanceWGS84(116.4570315, 34.8623005, 116.4660405, 34.8713095));
}
/**
* 判断是否为合规经度
*
* @param lon 经度
* @return
*/
public static Boolean isLegalLon(String lon) {
try {
return Double.valueOf(lon) >= -180 && Double.valueOf(lon) <= 180;
} catch (Exception exception) {
return false;
}
}
/**
* 判断是否为合规纬度
*
* @param lat 纬度
*/
public static Boolean isLegalLat(String lat) {
try {
return Double.valueOf(lat) >= -90 && Double.valueOf(lat) <= 90;
} catch (Exception exception) {
return false;
}
}
/**
* 根据WGS84坐标系经纬度计算距离
*
* @param lon1 经度
* @param lat1 纬度
* @param lon2 经度
* @param lat2 纬度
* @return
*/
public static double getDistanceWGS84(double lon1, double lat1, double lon2, double lat2) {
GlobalCoordinates from = new GlobalCoordinates(lat1, lon1);
GlobalCoordinates to = new GlobalCoordinates(lat2, lon2);
GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(Ellipsoid.WGS84, from, to);
return geoCurve.getEllipsoidalDistance();
}
/**
* 经纬度转墨卡托
*
* @param lon 经度
* @param lat 纬度
* @return
*/
public static double[] lonlat2XY(double lon, double lat) {
double[] xy = new double[2];
double x = lon * pi * longRadius / 180;
double y = Math.log(Math.tan((90 + lat) * pi / 360)) / (pi / 180);
y = y * pi * shortRadius / 180;
xy[0] = x;
xy[1] = y;
return xy;
}
/**
* 墨卡托转经纬度
*
* @param mercatorX X
* @param mercatorY Y
* @return
*/
public static double[] xy2Lonlat(double mercatorX, double mercatorY) {
double[] xy = new double[2];
double x = mercatorX / (pi * longRadius) * 180;
double y = mercatorY / (pi * shortRadius) * 180;
y = 180 / pi * (2 * Math.atan(Math.exp(y * pi / 180)) - pi / 2);
xy[0] = x;
xy[1] = y;
return xy;
}
/**
* 判断指定坐标是否在中国境内
*
* @param lat 纬度
* @param lon 经度
* @return
*/
public static boolean outOfChina(Double lat, Double lon) {
if (lon < 72.004 || lon > 137.8347) {
return true;
}
return lat < 0.8293 || lat > 55.8271;
}
/**
* WGS84转火星
*
* @param lat 纬度
* @param lon 经度
* @return
*/
public static Double[] wgs84ToGcj02(Double lat, Double lon) {
if (outOfChina(lat, lon)) {
return new Double[]{lat, lon};
}
Double dLat = transformLat(lon - 105.0, lat - 35.0);
Double dLon = transformLon(lon - 105.0, lat - 35.0);
Double radLat = lat / 180.0 * pi;
Double magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
Double sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
Double mgLat = lat + dLat;
Double mgLon = lon + dLon;
return new Double[]{mgLat, mgLon};
}
/**
* 火星转WGS84
*
* @param lat 纬度
* @param lon 经度
* @return
*/
public static Double[] gcj02ToWgs84(Double lat, Double lon) {
Double[] gps = transform(lat, lon);
Double lontitude = lon * 2 - gps[1];
Double latitude = lat * 2 - gps[0];
return new Double[]{latitude, lontitude};
}
/**
* 火星转百度
*
* @param lat 纬度
* @param lon 经度
* @return
*/
public static Double[] gcj02ToBd09(Double lat, Double lon) {
Double x = lon, y = lat;
Double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
Double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
Double tempLon = z * Math.cos(theta) + 0.0065;
Double tempLat = z * Math.sin(theta) + 0.006;
Double[] gps = {tempLat, tempLon};
return gps;
}
/**
* 百度转火星
*
* @param lat 纬度
* @param lon 经度
* @return
*/
public static Double[] bd09ToGcj02(Double lat, Double lon) {
Double x = lon - 0.0065, y = lat - 0.006;
Double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
Double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
Double tempLon = z * Math.cos(theta);
Double tempLat = z * Math.sin(theta);
Double[] gps = {tempLat, tempLon};
return gps;
}
/**
* WGS84转百度
*
* @param lat 纬度
* @param lon 经度
* @return
*/
public static Double[] wgs84ToBd09(Double lat, Double lon) {
Double[] gcj02 = wgs84ToGcj02(lat, lon);
Double[] bd09 = gcj02ToBd09(gcj02[0], gcj02[1]);
return bd09;
}
/**
* 百度转WGS84
*
* @param lat 纬度
* @param lon 经度
* @return
*/
public static Double[] bd09ToWgs84(Double lat, Double lon) {
Double[] gcj02 = bd09ToGcj02(lat, lon);
Double[] gps84 = gcj02ToWgs84(gcj02[0], gcj02[1]);
// 保留小数点后六位
gps84[0] = retain6(gps84[0]);
gps84[1] = retain6(gps84[1]);
return gps84;
}
/**
* 保留小数点后指定位数
*
* @param num 数值
* @param digits 小数点位数
* @return
*/
public static Double retain(Double num, Integer digits) {
String result = String.format("%." + digits + "f", num);
return Double.valueOf(result);
}
/**
* 指定图形类型和坐标串,拼接成WKT格式
*
* @param type 图形类型,
* @param coordinates 坐标串
* @return
*/
public static String convert2Wkt(String type, String coordinates) {
//"Point", "MultiPoint", "LineString", "MultiLineString", "Polygon", "MultiPolygon"
StringBuffer wkt = new StringBuffer();
JSONArray jsonArray = JSONObject.parseArray(coordinates);
type = type.toUpperCase();
switch (type) {
case "POINT":
//[100.0, 0.0]
wkt.append("POINT(").append(jsonArray.getString(0)).append(" ")
.append(jsonArray.getString(1)).append(")");
break;
case "MULTIPOINT":
//[
// [100.0, 0.0],
// [101.0, 1.0]
// ]
wkt.append("MULTIPOINT(");
for (int i = 0; i < jsonArray.size(); i++) {
JSONArray point = jsonArray.getJSONArray(i);
wkt.append(point.getString(0)).append(" ").append(point.get(1)).append(",");
}
wkt.deleteCharAt(wkt.length() - 1);
wkt.append(")");
break;
case "LINESTRING":
//和multipoint结构一样
//[
// [101.0, 0.0],
// [102.0, 1.0]
// ]
wkt.append("LINESTRING").append(wktLineString(jsonArray));
break;
case "MULTILINESTRING":
//[
// [
// [100.0, 0.0],
// [101.0, 1.0]
// ],
// [
// [102.0, 2.0],
// [103.0, 3.0]
// ]
// ]
wkt.append("MULTILINESTRING(");
for (int i = 0; i < jsonArray.size(); i++) {
wkt.append(wktLineString(jsonArray.getJSONArray(i))).append(",");
}
wkt.deleteCharAt(wkt.length() - 1);
wkt.append(")");
break;
case "POLYGON":
//POLYGON((1 1,5 1,5 5,1 5,1 1),(2 2,2 3,3 3,3 2,2 2))
//"coordinates": [
// [
// [-180.0, 10.0],
// [20.0, 90.0],
// [180.0, -5.0],
// [-30.0, -90.0]
// ]
// ]
wkt.append("POLYGON").append(wktPolygon(jsonArray));
break;
case "MULTIPOLYGON":
//解析为多个polygon
wkt.append("MULTIPOLYGON(");
for (int i = 0; i < jsonArray.size(); i++) {
wkt.append(wktPolygon(jsonArray.getJSONArray(i))).append(",");
}
wkt.deleteCharAt(wkt.length() - 1);
wkt.append(")");
break;
}
return wkt.toString();
}
private static Double retain6(Double num) {
return retain(num, 6);
}
private static String wktLineString(JSONArray jsonArray) {
StringBuffer wkt = new StringBuffer();
wkt.append("(");
for (int i = 0; i < jsonArray.size(); i++) {
JSONArray point = jsonArray.getJSONArray(i);
wkt.append(point.getString(0)).append(" ").append(point.get(1)).append(",");
}
wkt.deleteCharAt(wkt.length() - 1);
wkt.append(")");
return wkt.toString();
}
private static String wktPolygon(JSONArray jsonArray) {
StringBuffer wkt = new StringBuffer();
wkt.append("(");
for (int i = 0; i < jsonArray.size(); i++) {
//是一组组的LineString
wkt.append("(");
JSONArray lineString = jsonArray.getJSONArray(i);
for (int j = 0; j < lineString.size(); j++) {
JSONArray pointArray = lineString.getJSONArray(j);
wkt.append(pointArray.getString(0)).append(" ").append(pointArray.getString(1))
.append(",");
}
if (wkt.length() > 0) {
//删除最后一个逗号
wkt.deleteCharAt(wkt.length() - 1);
}
wkt.append("),");
}
if (wkt.length() > 0) {
wkt.deleteCharAt(wkt.length() - 1);
}
wkt.append(")");
return wkt.toString();
}
private static Double transformLat(Double x, Double y) {
Double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y
+ 0.2 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
return ret;
}
private static Double transformLon(Double x, Double y) {
Double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1
* Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0
* pi)) * 2.0 / 3.0;
return ret;
}
private static Double[] transform(Double lat, Double lon) {
if (outOfChina(lat, lon)) {
return new Double[]{lat, lon};
}
Double dLat = transformLat(lon - 105.0, lat - 35.0);
Double dLon = transformLon(lon - 105.0, lat - 35.0);
Double radLat = lat / 180.0 * pi;
Double magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
Double sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
Double mgLat = lat + dLat;
Double mgLon = lon + dLon;
return new Double[]{mgLat, mgLon};
}
}
功能代码
新建class继承UDF,调用GisUtil类实现相应功能即可
/**
* 使用方法:百度坐标系转火星坐标系
* > add jar ..../udfforhive-1.0-SNAPSHOT.jar;
* > create temporary function bd09togcj02 as "com.oidd.udf.hive.Bd09ToGcj02";
* > select bd09togcj02(118.74231624081231, 32.068722091339836);
*/
public class Bd09ToGcj02 extends UDF {
public static void main(String[] args) {
System.out.println(new Bd09ToGcj02().evaluate(118.74231624081231, 32.068722091339836));
}
public String evaluate(double lon, double lat) {
Double[] coord = GisUtil.bd09ToGcj02(lat, lon);
return String.format("%f,%f", coord[1], coord[0]);
}
}
打包上传
pom.xml配置如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gis.hive</groupId>
<artifactId>gisutilforhive</artifactId>
<version>1.0-SNAPSHOT</version>
<name>gisutilforhive</name>
<description>为Hive提供GIS相关方法支持,如坐标转换、距离计算等</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<scala.version>2.11</scala.version>
<spark.version>2.2.0</spark.version>
<geotools.version>14.1</geotools.version>
</properties>
<repositories>
<repository>
<id>osgeo</id>
<name>OSGeo Release Repository</name>
<url>https://repo.osgeo.org/repository/release/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
<repository>
<id>osgeo-snapshot</id>
<name>OSGeo Snapshot Repository</name>
<url>https://repo.osgeo.org/repository/snapshot/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<repository>
<id>public</id>
<name>aliyun nexus</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<dependencies>
<!-- Hive支持 -->
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>${spark.version}</version>
</dependency>
<!-- JSON处理 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.4</version>
</dependency>
<!-- GEOJSON处理 -->
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-geojson</artifactId>
<version>${geotools.version}</version>
</dependency>
<!-- 经纬度计算距离 -->
<dependency>
<groupId>org.gavaghan</groupId>
<artifactId>geodesy</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>assembly</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
打包完成后,上传至Hive客户端,可以是本地目录,也可以是HDFS目录,建议使用HDFS目录,便于全局使用。
上传至本地目录
/gis/lib/gisutilforhive-1.0-SNAPSHOT.jar
上传至HDFS
hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar
方法注册
方式1:临时使用
hive
# 本地目录
hive> add jar /gis/lib/gisutilforhive-1.0-SNAPSHOT.jar;
# 远程HDFS
hive> add jar hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar;
# 创建临时函数
hive> create temporary function Bd09ToGcj02 as 'common.gis.hive.Bd09ToGcj02';
hive> create temporary function Bd09ToWgs84 as 'common.gis.hive.Bd09ToWgs84';
hive> create temporary function Convert2Wkt as 'common.gis.hive.Convert2Wkt';
hive> create temporary function Gcj02ToBd09 as 'common.gis.hive.Gcj02ToBd09';
hive> create temporary function Gcj02ToWgs84 as 'common.gis.hive.Gcj02ToWgs84';
hive> create temporary function OutOfChina as 'common.gis.hive.OutOfChina';
hive> create temporary function Retain as 'common.gis.hive.Retain';
hive> create temporary function Wgs84ToBd09 as 'common.gis.hive.Wgs84ToBd09';
hive> create temporary function Wgs84ToGcj02 as 'common.gis.hive.Wgs84ToGcj02';
hive> create temporary function LL2XY as 'common.gis.hive.LL2XY';
hive> create temporary function XY2LL as 'common.gis.hive.XY2LL';
hive> create temporary function GetDistance as 'common.gis.hive.GetDistance';
hive> create temporary function IsLegalLon as 'common.gis.hive.IsLegalLon';
hive> create temporary function IsLegalLat as 'common.gis.hive.IsLegalLat';
# 测试
hive> select OutOfChina(0,0);
OK
true
Time taken: 0.52 seconds, Fetched: 1 row(s)
方式2:全局使用
hive
# 创建全局函数
hive> drop function if exists Bd09ToGcj02; create function Bd09ToGcj02 as 'common.gis.hive.Bd09ToGcj02' using jar 'hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar';
hive> drop function if exists Bd09ToWgs84; create function Bd09ToWgs84 as 'common.gis.hive.Bd09ToWgs84' using jar 'hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar';
hive> drop function if exists Convert2Wkt; create function Convert2Wkt as 'common.gis.hive.Convert2Wkt' using jar 'hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar';
hive> drop function if exists Gcj02ToBd09; create function Gcj02ToBd09 as 'common.gis.hive.Gcj02ToBd09' using jar 'hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar';
hive> drop function if exists Gcj02ToWgs84; create function Gcj02ToWgs84 as 'common.gis.hive.Gcj02ToWgs84' using jar 'hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar';
hive> drop function if exists OutOfChina; create function OutOfChina as 'common.gis.hive.OutOfChina' using jar 'hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar';
hive> drop function if exists Retain; create function Retain as 'common.gis.hive.Retain' using jar 'hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar';
hive> drop function if exists Wgs84ToBd09; create function Wgs84ToBd09 as 'common.gis.hive.Wgs84ToBd09' using jar 'hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar';
hive> drop function if exists Wgs84ToGcj02; create function Wgs84ToGcj02 as 'common.gis.hive.Wgs84ToGcj02' using jar 'hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar';
hive> drop function if exists LL2XY; create function LL2XY as 'common.gis.hive.LL2XY' using jar 'hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar';
hive> drop function if exists XY2LL; create function XY2LL as 'common.gis.hive.XY2LL' using jar 'hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar';
hive> drop function if exists GetDistance; create function GetDistance as 'common.gis.hive.GetDistance' using jar 'hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar';
hive> drop function if exists IsLegalLon; create function IsLegalLon as 'common.gis.hive.IsLegalLon' using jar 'hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar';
hive> drop function if exists IsLegalLat; create function IsLegalLat as 'common.gis.hive.IsLegalLat' using jar 'hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar';
hive> quit;
hive
# 测试
hive> select OutOfChina(0,0);
converting to local hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar
Added [/tmp/5beee0f5-63f9-4f18-a41d-1cd136ee0645_resources/gisutilforhive-1.0-SNAPSHOT.jar] to class path
Added resources: [hdfs://ip:port/libs/gisutilforhive-1.0-SNAPSHOT.jar]
OK
true
Time taken: 2.155 seconds, Fetched: 1 row(s)
方法示例
百度坐标系转火星坐标系
select bd09togcj02(118.74231624081231, 32.068722091339836);
百度坐标系转WGS84坐标系
select bd09towgs84(118.74231624081231, 32.068722091339836);
坐标转WKT格式
select convert2wkt(“POINT”, “[118.74231624081231, 32.068722091339836]”));
火星坐标系转百度坐标系
select gcj02tobd09(118.74231624081231, 32.068722091339836);
火星坐标系转WGS84坐标系
select gcj02towgs84(118.74231624081231, 32.068722091339836);
WGS84坐标系经纬度计算距离
select xy2ll(13218334.179541,3759686.929327);
经纬度转米制坐标
select ll2xy(118.74231624081231, 32.068722091339836);
判断指定位置是否在国内,WGS84坐标系
select outofchina(118.74231624081231, 32.068722091339836);
保留至小数后指定位数
select retain(118.74231624081231,4);
WGS84坐标系转百度坐标系
select wgs84tobd09(118.74231624081231, 32.068722091339836);
WGS84坐标系转火星坐标系
select wgs84togcj02(118.74231624081231, 32.068722091339836);
米制转经纬度坐标
select xy2ll(13218334.179541,3759686.929327);
是否为合规经度
select islegallon(118.74231624081231);
是否为合规纬度
select islegallat(32.068722091339836);