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

org.anyline.qq.map.util.QQMapClient Maven / Gradle / Ivy

There is a newer version: 8.7.2-20250110
Show newest version
/*
 * Copyright 2006-2023 www.anyline.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */




package org.anyline.qq.map.util;

import org.anyline.client.map.AbstractMapClient;
import org.anyline.client.map.MapClient;
import org.anyline.entity.Coordinate;
import org.anyline.entity.DataRow;
import org.anyline.entity.SRS;
import org.anyline.exception.AnylineException;
import org.anyline.net.HttpResponse;
import org.anyline.net.HttpUtil;
import org.anyline.util.AnylineConfig;
import org.anyline.util.BasicUtil;
import org.anyline.util.BeanUtil;
import org.anyline.util.encrypt.MD5Util;
import org.anyline.log.Log;
import org.anyline.log.LogProxy;

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

public class QQMapClient extends AbstractMapClient implements MapClient {
    private static Log log = LogProxy.get(QQMapClient.class);
    public QQMapConfig config = null;
    private static Hashtable instances = new Hashtable<>();

    static {
        Hashtable configs = QQMapConfig.getInstances();
        for(String key:configs.keySet()){
            instances.put(key, getInstance(key));
        }
    }
    public static Hashtable getInstances(){
        return instances;
    }
    public QQMapConfig getConfig(){
        return config;
    }
    public static QQMapClient getInstance() {
        return getInstance("default");
    }

    public static QQMapClient getInstance(String key) {
        if (BasicUtil.isEmpty(key)) {
            key = "default";
        }
        QQMapClient client = instances.get(key);
        if (null == client) {
            QQMapConfig config = QQMapConfig.getInstance(key);
            if(null != config) {
                client = new QQMapClient();
                client.config = config;
                instances.put(key, client);
            }
        }
        return client;
    }


    /**
     * 通过IP地址获取其当前所在地理位置
     * @param ip ip
     * @return 坐标
     */
    @Override
    public Coordinate ip(String ip) {
        Coordinate coordinate = null;
        String api = "/ws/location/v1/ip";
        Map params = new HashMap<>();
        params.put("ip", ip);
        params.put("key", config.KEY);
        DataRow row = api(api, params);
        if(null != row){
            coordinate = new Coordinate();
            DataRow result = row.getRow("result");
            if(null != result) {
                DataRow point = result.getRow("location");
                if(null != point){
                    coordinate.setLng(point.getDouble("lng", -1.0));
                    coordinate.setLat(point.getDouble("lat", -1.d));
                }
                DataRow ad = result.getRow("ad_info");
                if(null != ad){
                    coordinate.setProvinceName(ad.getString("province"));
                    coordinate.setCityName(ad.getString("city"));
                    coordinate.setCountyName(ad.getString("district"));
                    coordinate.setCountyCode(ad.getString("adcode"));
                }
            }
        }
        if(null != coordinate) {
            coordinate.setSrs(SRS.GCJ02LL);
        }
        if(null != coordinate) {
            coordinate.correct();
        }
        return coordinate;
    }

    /**
     * 根据地址解析 坐标
     * https://lbs.qq.com/service/webService/webServiceGuide/webServiceGeocoder
     * @param address 地址 用原文签名 用url encode后提交
     * @param city 城市(没有用到可以不传)
     * @return Coordinate
     */
    @Override
    public Coordinate geo(String address, String city){
        Coordinate coordinate = new Coordinate();
        coordinate.setAddress(address);
        if(null != address){
            address = address.replace(" ","");
            if(null != city && !address.contains(city)){
                address = city + address;
            }
        }
        String api = "/ws/geocoder/v1";
        Map params = new HashMap<>();
        params.put("address", address);
        DataRow row = api(api, params);
        if(null != row){
            DataRow result = row.getRow("result");
            DataRow location = row.getRow("result","location");
            if(null != location){
                coordinate.setLat(location.getString("lat"));
                coordinate.setLng(location.getString("lng"));
            }

            DataRow adr = row.getRow("result","address_components");
            if(null != adr) {
                coordinate.setProvinceName(adr.getString("province"));
                coordinate.setCityName(adr.getString("city"));
                coordinate.setCountyName(adr.getString("district"));
                String street = adr.getString("street");
                coordinate.setStreet(street);
                String number = adr.getString("street_number");
                if(null != number && null != street){
                    number = number.replace(street,"");
                }
                coordinate.setStreetNumber(number);
            }
            adr = row.getRow("result","ad_info");
            if(null != adr) {
                String adcode = adr.getString("adcode");
                String provinceCode = adcode.substring(0,2);
                String cityCode = adcode.substring(0,4);
                coordinate.setProvinceCode(provinceCode);
                coordinate.setCityCode(cityCode);
                coordinate.setCountyCode(adcode);
            }
            coordinate.setReliability(result.getInt("reliability",0));
            coordinate.setAccuracy(result.getInt("level",0));
            coordinate.setSuccess(true);

        }
        if(null != coordinate) {
            coordinate.correct();
        }
        return coordinate;
    }
    /**
     * 逆地址解析 根据坐标返回详细地址及各级地区编号
     * https://lbs.qq.com/service/webService/webServiceGuide/webServiceGcoder
     * @param coordinate 坐标
     * @return Coordinate
     */
    @Override
    public Coordinate regeo(Coordinate coordinate){
        String api = "/ws/geocoder/v1";

        SRS _type = coordinate.getSrs();
        Double _lng = coordinate.getLng();
        Double _lat = coordinate.getLat();

        coordinate.convert(SRS.GCJ02LL);
        coordinate.setSuccess(false);

        Map params = new HashMap<>();
        params.put("location", coordinate.getLat()+","+coordinate.getLng());        // 这里是纬度在前

        // 换回原坐标系
        coordinate.setLng(_lng);
        coordinate.setLat(_lat);
        coordinate.setSrs(_type);

        DataRow row = api(api, params);
        if(null != row){
            DataRow result = row.getRow("result");
            if(null != result) {
                coordinate.setAddress(result.getString("address"));
            }
            DataRow adr = row.getRow("result","address_component");
            if(null != adr) {
                coordinate.setProvinceName(adr.getString("province"));
                coordinate.setCityName(adr.getString("city"));
                coordinate.setCountyName(adr.getString("district"));

                String street = adr.getString("street");
                coordinate.setStreet(street);
                String number = adr.getString("street_number");
                if(null != number && null != street){
                    number = number.replace(street,"");
                }
            }
            adr = row.getRow("result","ad_info");
            if(null != adr) {
                String adcode = adr.getString("adcode");
                if(BasicUtil.isNotEmpty(adcode)) {
                    String provinceCode = adcode.substring(0, 2);
                    String cityCode = adcode.substring(0, 4);
                    coordinate.setProvinceCode(provinceCode);
                    coordinate.setCityCode(cityCode);
                    coordinate.setCountyCode(adcode);
                }
            }
            adr = row.getRow("result","address_reference","town");
            if(null != adr){
                coordinate.setTownCode(adr.getString("id"));
                coordinate.setTownName(adr.getString("title"));
            }
            coordinate.setSuccess(true);

        }
        if(null != coordinate) {
            coordinate.correct();
        }
        return coordinate;
    }



    /**
     * 参数签名
     * @param api 接口
     * @param params 参数
     * @return String
     */
    private String sign(String api, Map params){
        params.put("key", config.KEY);
        String sign = null;
        String src = api + "?" + BeanUtil.map2string(params) + config.SECRET;
        sign = MD5Util.crypto(src);
        params.put("sig", sign);
        return sign;
    }
    private DataRow api(String api, Map params){
        DataRow row = null;
        sign(api, params);
        HttpResponse response = HttpUtil.get(QQMapConfig.HOST + api,"UTF-8", params);
        int status = response.getStatus();
        if(status == 200){
            String txt = response.getText();
            row = DataRow.parseJson(txt);
            if(null == row){
                status = row.getInt("status",-1);
                if(status != 0) {
                    log.warn("[{}][执行失败][status:{}][info:{}]", api , status, row.getString("message"));
                    log.warn("[{}][response:{}]", api, txt);
                    if ("302".equals(status)) {
                        throw new AnylineException("API_OVER_LIMIT", "访问已超出日访问量");
                    } else if ("401".equals(status) || "402".equals(status)) {
                        try {
                            log.warn("并发量已达到上限,sleep 50 ...");
                            Thread.sleep(50);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        api(api, params);
                    } else {
                        throw new AnylineException(status, row.getString("message"));
                    }
                }
            }
        }
        return row;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy