All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hn.map.qq.LocationUtil Maven / Gradle / Ivy

There is a newer version: 1.0.18
Show newest version
package com.hn.map.qq;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.hn.config.HnConfigUtils;
import com.hn.config.exception.ConfigException;
import com.hn.map.MapException;
import com.hn.map.qq.domain.AddressComponent;
import com.hn.map.qq.domain.Location;
import com.hn.utils.AssertUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 描述:
 * 位置工具类 腾讯地图
 * 
 * 域名白名单:
 *   适用于浏览器端JSONP方式调用Webservice服务
 *   1.仅白名单中的域名才可使用此key调用WebService服务,留空则不限制
 *   2.每行填写一个域名,填写的域名及其子域名都会同时得到授权,如:qq.com,则qq.com下的子域名map.qq.com也可以使用此key
 *
 * 授权ip:
 *   授权指定IP来源的请求才可使用,每行填写一条,留空则不限制
 *   1.填写单一授权IP,例:202.106.0.99
 *   2.填写授权地址段,起始IP-结束IP。例:202.106.0.20-202.106.0.26
 *
 * 签名计算:
 *   通过签名校验的方式,可有效解决请求伪造,稍有开发量,但与授权IP方式比较,不必担心服务器换IP的问题。
 *
* @author fei * 2019-12-30 18:31 */ public class LocationUtil { private static final Log log = LogFactory.get(); /** * 开发密钥 */ private static String key; private static final String GEN_URL = "https://apis.map.qq.com"; /** * 请求地址 */ private static final String REQ_URL = "/ws/geocoder/v1/"; static { // 初始化key key = getKey(""); } /** * 读取对应场景的key * * @param scene 场景 */ public static void scene(String scene) { // 这样会存在线程安全问题 key = getKey(scene); } /** * 逆地址解析(坐标位置描述) * * @param lat 纬度 * @param lng 经度 * @return addressComponent {@link AddressComponent} */ public static AddressComponent locationToAddress(double lat, double lng) { Map param = new HashMap<>(3); param.put("key", key); // 是否返回周边POI列表: 1.返回;0不返回(默认) // param.put("get_poi", 1); // param.put("poi_options","address_format=short"); // 返回格式:支持JSON/JSONP,默认JSON // param.put("output", "JSON"); param.put("location", lat + "," + lng); // 加密 String secretKey = getSecretKey(""); if (StrUtil.isNotBlank(secretKey)) { param.put("sig", sign(lat, lng)); } String resultStr = HttpUtil.get(GEN_URL + REQ_URL, param); log.debug("[腾讯地图]逆地址解析(坐标位置描述) 返回结果:{}", resultStr); JSONObject resultObject = JSONUtil.parseObj(resultStr); if (resultObject.getInt("status") == 0) { JSONObject result = resultObject.getJSONObject("result"); return JSONUtil.toBean(result.getStr("address_component"), AddressComponent.class); } throw new MapException("[腾讯地图]逆地址解析失败:" + resultObject.getStr("message")); } /** * 地址解析(地址转坐标) * * @param address 地址 (注:地址中请包含城市名称,否则会影响解析效果) * @return 坐标信息 {@link Location} */ public static Location addressToLocation(String address) { Map param = new HashMap<>(); param.put("key", key); // 返回格式:支持JSON/JSONP,默认JSON // param.put("output", "JSON"); param.put("address", address); // 加密 String secretKey = getSecretKey(""); if (StrUtil.isNotBlank(secretKey)) { param.put("sig", sign(address)); } String resultStr = HttpUtil.get(GEN_URL + REQ_URL, param); log.debug("[腾讯地图]地址解析(地址转坐标) 返回结果:{}", resultStr); JSONObject resultObject = JSONUtil.parseObj(resultStr); if (resultObject.getInt("status") == 0) { JSONObject result = resultObject.getJSONObject("result"); JSONObject location = result.getJSONObject("location"); return new Location(location.getDouble("lat"), location.getDouble("lng")); } throw new MapException("【腾讯地图】地址解析(地址转坐标)失败:" + resultObject.getStr("message")); } /** * 签名计算 *
     *   1. 首先对参数进行排序:按参数名升序(本例结果为key在前,location在后):
     *   2. 签名计算(sig):请求路径+”?”+请求参数+SK进行拼接,并计算拼接后字符串md5值,即为签名(sig):
     *   md5("/ws/geocoder/v1?key=5Q5BZ-5EVWJ-SN5F3-*****&location=28.7033487,115.8660847SWvT26ypwq5Nwb5RvS8cLi6NSoH8HlJX")
     *   3. 生成最终请求:将计算得到的签名sig,放到请求中(参数名即为:sig):
     * 
* @param lat 纬度 * @param lng 经度 * @return 签名计算后的结果 */ private static String sign(double lat, double lng) { String secretKey = getSecretKey(""); String location = lat + "," + lng; return SecureUtil.md5(REQ_URL + "?key=" + key + "&location=" + location + secretKey); } /** * 签名计算 * * @param address 地址 * @return 签名计算后的结果 */ private static String sign(String address) { String secretKey = getSecretKey(""); return SecureUtil.md5(REQ_URL + "?address=" + address + "&key=" + key + secretKey); } /** * 配置前缀名 */ private static final String CONFIG_KEY = "map.qq"; private static String getKey(String scene) { if (StrUtil.isNotBlank(scene)) { scene = "-".concat(scene); } String key = HnConfigUtils.getConfig(CONFIG_KEY.concat(scene).concat(".key")); AssertUtils.notNull(key, ConfigException.exception("腾讯地图key未配置")); return key; } private static String getSecretKey(String scene) { if (StrUtil.isNotBlank(scene)) { scene = "-".concat(scene); } return HnConfigUtils.getConfig(CONFIG_KEY.concat(scene).concat(".secretKey")); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy