Java 工具类 - 地图工具类 MapUtil

1.根据经纬度计算两点之间的距离
2.坐标转换
3.根据城市获取经纬度

package com.tgb.hz.common;

import com.tgb.hz.common.entity.Point;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;

/**
 * 地图工具类
 * 
 * @author hezhao
 * @Time 2017年7月31日 下午8:38:50
 */
public class MapUtil {

    private static double EARTH_RADIUS = 6378137;// 赤道半径(单位m)
    private final static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;

    /**
     * 转化为弧度(rad)
     * */
    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }

    /**
     * 基于googleMap中的算法得到两经纬度之间的距离,计算经度与谷歌地图的距离经度差不多,相差范围在0.2米以下
     * 
     * @param lon1
     *            第一点的经度
     * @param lat1
     *            第一点的纬度
     * @param lon2
     *            第二点的经度
     * @param lat2
     *            第二点的纬度
     * @return 返回的距离,单位km
     * */
    public static double distance(double lon1, double lat1, double lon2,
            double lat2) {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lon1) - rad(lon2);
        double 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;
        return s / 1000;
    }

    /**
     * 基于googleMap中的算法得到两经纬度之间的距离,计算经度与谷歌地图的距离经度差不多,相差范围在0.2米以下
     * 
     * @param lon1
     *            第一点的经度
     * @param lat1
     *            第一点的纬度
     * @param lon2
     *            第二点的经度
     * @param lat2
     *            第二点的纬度
     * @return 返回的距离,单位m
     * */
    public static double distance2(double lon1, double lat1, double lon2,
            double lat2) {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lon1) - rad(lon2);
        double 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 = Math.round(s * 10000) / 10000;
        return s;
    }

    /**
     * 坐标转换,腾讯地图转换成百度地图坐标
     * 
     * @param lat
     *            腾讯纬度
     * @param lon
     *            腾讯经度
     * @return 返回结果:经度,纬度
     */
    public static Point map_tx2bd(BigDecimal lat, BigDecimal lon) {
        double bd_lat;
        double bd_lon;
        double x = lon.doubleValue(), y = lat.doubleValue();
        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);
        bd_lon = z * Math.cos(theta) + 0.0065;
        bd_lat = z * Math.sin(theta) + 0.006;

        return new Point(BigDecimal.valueOf(bd_lat), BigDecimal.valueOf(bd_lon));
    }

    /**
     * 坐标转换,百度地图坐标转换成腾讯地图坐标
     * 
     * @param lat
     *            百度坐标纬度
     * @param lon
     *            百度坐标经度
     * @return 返回结果:纬度,经度
     */
    public static Point map_bd2tx(BigDecimal lat, BigDecimal lon) {
        double tx_lat;
        double tx_lon;
        double x = lon.doubleValue() - 0.0065, y = lat.doubleValue() - 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);
        tx_lon = z * Math.cos(theta);
        tx_lat = z * Math.sin(theta);
        return new Point(BigDecimal.valueOf(tx_lat), BigDecimal.valueOf(tx_lon));
    }

    /**
     * 根据城市地区查询经纬度信息
     * @param city
     *            城市中文名称
     * @return String
     */
    public static String findLatLng(String city) {
        if (null != city && !"".equals(city)) {
            StringBuilder resultBuilder = new StringBuilder();
            Document doc;
            try {
                String address = URLEncoder.encode(city, "utf-8");
                doc = Jsoup
                        .connect(
                                "http://api.map.baidu.com/geocoder?address="
                                        + address
                                        + "&output=xml&key=37492c0ee6f924cb5e934fa08c6b1676")
                        .timeout(30000).get();
                if (null != doc) {
                    Elements location = doc.select("body")
                            .select("geocodersearchresponse").select("result")
                            .select("location");
                    if (location != null && !"".equals(location)) {
                        if (location.select("lng").text() != null
                                && !location.select("lng").text().equals("")) {
                            resultBuilder.append(location.select("lng").text()
                                    + ",");
                            resultBuilder.append(location.select("lat").text());
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (resultBuilder.toString().indexOf(",") != -1) {
                return resultBuilder.toString();
            } else {
                return "114.025974,22.546054";// 默认深圳经纬度
            }
        }

        return "114.025974,22.546054";// 默认深圳经纬度
    }

    public static void main(String[] args) {
        // 济南国际会展中心经纬度:117.11811 36.68484
        // 趵突泉:117.00999000000002 36.66123
        System.out.println(distance(117.11811, 36.68484, 117.00999000000002,
                36.66123));
        System.out.println(distance2(117.11811, 36.68484, 117.00999000000002,
                36.66123));
        System.out.println(findLatLng("上海"));
    }
}
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值