数据分析中,我们经常遇到经纬度相关的GIS处理,但Hive本身并不支持,我们可以通过自定义实现UDF函数的方法进行实现。

源码下载

https://github.com/Angryshark128/gisutilforhive.git

类包下载

链接:https://pan.baidu.com/s/19-bZz9ttX-RW6-7nNiBGPw

提取码:ap99

实现步骤

  1. 代码实现
  2. 打包上传
  3. 注册测试

代码实现

核心代码

实现在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);