package com.jzdsh.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.HttpKit;
import com.jfinal.kit.PropKit;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @description: 高德地图工具类
 * @author: lc
 * @create 2019-08-22  17:08
 */
public class MapUtils {


    /**
     * 地球半径,单位 km
     */
    private static final double EARTH_RADIUS = 6378.137;


    /**
     * 地理编码url
     *
     * @param address 输入位置信息  "上海市静安区上海火车站"
     * @return url
     */
    public static String getGeoUrl(String address) {
        return "https://restapi.amap.com/v3/geocode/geo?key=" + PropKit.get("key") + "&address=" + address;
    }

    /**
     * 逆地理编码url
     *
     * @param location 经纬度  "121.455625,31.250202"
     * @return url
     */
    public static String getRegeoUrl(String location) {
        return "https://restapi.amap.com/v3/geocode/regeo?key=" + PropKit.get("key") + "&location=" + location;
    }

    /**
     * 向指定URL发送GET方法的请求
     *
     * @param url 发送请求的URL
     * @return 远程资源的响应结果
     */
    public static String sendGet(String url) {

        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection( );
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect( );
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream( ), "UTF-8"));
            String line;
            while ((line = in.readLine( )) != null) {
                result += line;
            }
        } catch (Exception e) {
            return null;
        } finally { // 使用finally块来关闭输入流
            try {
                if (in != null) {
                    in.close( );
                }
            } catch (Exception e2) {
                e2.printStackTrace( );
            }
        }
        return result;
    }

    /**
     * 输入地址 返回信息 （已转码）
     *
     * @param address
     * @return jsonStr
     */
    public static String sendAddress(String address) {
        //net.sf.json.JSONObject get = HttpRequestUtil.httpRequest("https://restapi.amap.com/v3/geocode/geo", "GET", "address=" + address + "&key=" + WxConfig.MAP_KEY + "");
        //return get.toString( );
        return HttpKit.get("https://restapi.amap.com/v3/geocode/geo?address=" + address + "&key=" + PropKit.get("key"));
    }

    public static String getProvince(String jsonStr) {
        String addressComponent = JSONObject.parseObject(jsonStr).getJSONObject("regeocode").getString("addressComponent");
        String province = JSONObject.parseObject(addressComponent).getString("province");
        return province;
    }

    public static String getCity(String jsonStr) {
        String addressComponent = JSONObject.parseObject(jsonStr).getJSONObject("regeocode").getString("addressComponent");
        String city = JSONObject.parseObject(addressComponent).getString("city");
        return city;
    }

    /**
     * 获取区域名称
     *
     * @param jsonStr 远程资源响应结果
     * @return 列： "静安区"
     */
    public static String getDistrict(String jsonStr) {
        String addressComponent = JSONObject.parseObject(jsonStr).getJSONObject("regeocode").getString("addressComponent");
        String district = JSONObject.parseObject(addressComponent).getString("district");
        return district;
    }

    /**
     * 区域code
     *
     * @param jsonStr
     * @return
     */
    public static String getAdcode(String jsonStr) {
        String addressComponent = JSONObject.parseObject(jsonStr).getJSONObject("regeocode").getString("addressComponent");
        String adcode = JSONObject.parseObject(addressComponent).getString("adcode");
        return adcode;
    }

    /**
     * 获取全地理位置名称
     *
     * @param jsonStr 远程资源响应结果
     * @return 列： "上海市静安区上海火车站"
     */
    public static String getAddressNameByGeocoder(String jsonStr) {
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        String addressName = jsonObject.getJSONObject("regeocode").getString("formatted_address");
        if ("[]".equals(addressName)) {
            return "";
        }
        return addressName;
    }

    /**
     * 获取经纬度
     *
     * @param jsonStr 远程资源响应结果
     * @return 列： "121.455625,31.250202"
     */
    public static String getLongitudeAndLatitude(String jsonStr) {
        String location = ""; //经纬度
        JSONArray geocodes = JSONObject.parseObject(jsonStr).getJSONArray("geocodes");
        if (geocodes != null && geocodes.size( ) != 0) {
            for (Object geocode : JSONObject.parseObject(jsonStr).getJSONArray("geocodes")) {
                location = JSONObject.parseObject(geocode.toString( )).get("location").toString( );
            }
        }
        return location;
    }

    public static String getLongitudeLatitude(String address) {
        return getLongitudeAndLatitude(sendAddress(address));
    }


    /**
     * 根据经纬度，计算两点间的距离
     *
     * @param longitude1 第一个点的经度
     * @param latitude1  第一个点的纬度
     * @param longitude2 第二个点的经度
     * @param latitude2  第二个点的纬度
     * @return 返回距离 单位千米
     */
    public static double getDistance(double longitude1, double latitude1, double longitude2, double latitude2) {
        // 纬度
        double lat1 = Math.toRadians(latitude1);
        double lat2 = Math.toRadians(latitude2);
        // 经度
        double lng1 = Math.toRadians(longitude1);
        double lng2 = Math.toRadians(longitude2);
        // 纬度之差
        double a = lat1 - lat2;
        // 经度之差
        double b = lng1 - lng2;
        // 计算两点距离的公式
        double s = 2 * Math.asin(Math
                .sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2)));
        // 弧长乘地球半径, 返回单位: 千米
        s = s * EARTH_RADIUS;
        return s;
    }

    /**
     * 根据经纬度返回 省市县 地区
     *
     * @param longitude 经度
     * @param latitude  维度
     * @return map
     */
    public static Map< String, String > getMap(String longitude, String latitude) {
        HashMap< String, String > map = new HashMap<>( );
        if (StringUtils.isBlank(longitude) || Objects.equals("undefined", longitude)) {
            map.put("province", "");
            map.put("city", "");
            map.put("district", "");
            return map;
        }
        //-- 获取当前地理信息 区域
        String url = getRegeoUrl(longitude + "," + latitude);
        String jsonStr = MapUtils.sendGet(url);
        String province = MapUtils.getProvince(jsonStr);
        String city = MapUtils.getCity(jsonStr);
        String district = MapUtils.getDistrict(jsonStr);
        if (CommonCons.BRACKETS.equals(city)) {
            city = province;
        }
        map.put("province", province);
        map.put("city", city);
        map.put("district", district);
        return map;
    }

    public static void main(String[] args) {
        getLongitudeLatitude("上海市上海市普陀区祁连山南路588弄1号");


    }


}
