java调用百度的接口获取起-止位置的距离
作者:yfs1024 发布时间:2023-08-11 17:14:27
需求:校验收货地址是否超出配送范围
重要:
做该需求的思路就是通过卖家和卖家具体的地址信息,来获取到二者的经纬度, 此时可以使用百度的 "地理编码服务",即可获取对应的经纬度
第二步,就是通过二者的经纬度,按照百度接口的要求,发送,即可获取到包含二者距离的JSON串, 此时就可以通过解析JSON获取距离, 最后在判断得到的距离,与自己配送的距离进行比较,即可判断是否超出距离
注册一个百度账号,要求是必须实名认证,需要填写一些基本信息,这里需要注意一下.
首先要获取百度地图的一个AK
登录百度地图开放平台:https://lbsyun.baidu.com/
进入控制台,创建应用,获取AK:
创建应用时:
类型:选服务端
IP白名单:0.0.0.0/0
对于此需求用到了两个百度的接口, 接口地址如下:
地理编码服务: https://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding
https://lbsyun.baidu.com/index.php?title=webapi/directionlite-v1
代码编写:
1. 配置基本属性
sky:
baidumap:
shop-address: 北京市西城区广安门内大街167号翔达大厦1层
ak: XXXXXXXXXXXXXXXXXXXXXXXXXX
default-distance: 5000 // 这里在本文中没有使用,
用于发送请求的工具类
说明,因为现在我们需要从服务器中发送请求,此时我们就需要使用HttpClient这个小框架来实现此功能, 下面的工具类是对此框架的一个封装
package com.sky.utils;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Http工具类
*/
@Slf4j
public class HttpClientUtil {
static final int TIMEOUT_MSEC = 5 * 1000;
/**
* 发送GET方式请求
*
* @param url
* @param paramMap
* @return
*/
public static String doGet(String url, Map<String, String> paramMap) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
String result = "";
CloseableHttpResponse response = null;
try {
URIBuilder builder = new URIBuilder(url);
if (paramMap != null) {
for (String key : paramMap.keySet()) {
builder.addParameter(key, paramMap.get(key));
}
}
URI uri = builder.build();
log.info("发送的请求====>{}", uri);
//创建GET请求
HttpGet httpGet = new HttpGet(uri);
//发送请求
response = httpClient.execute(httpGet);
//判断响应状态
if (response.getStatusLine().getStatusCode() == 200) {
result = EntityUtils.toString(response.getEntity(), "UTF-8");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/**
* 发送POST方式请求
*
* @param url
* @param paramMap
* @return
* @throws IOException
*/
public static String doPost(String url, Map<String, String> paramMap) throws IOException {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建参数列表
if (paramMap != null) {
List<NameValuePair> paramList = new ArrayList();
for (Map.Entry<String, String> param : paramMap.entrySet()) {
paramList.add(new BasicNameValuePair(param.getKey(), param.getValue()));
}
// 模拟表单
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
httpPost.setEntity(entity);
}
httpPost.setConfig(builderRequestConfig());
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
} catch (Exception e) {
throw e;
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
/**
* 发送POST方式请求
*
* @param url
* @param paramMap
* @return
* @throws IOException
*/
public static String doPost4Json(String url, Map<String, String> paramMap) throws IOException {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
if (paramMap != null) {
//构造json格式数据
JSONObject jsonObject = new JSONObject();
for (Map.Entry<String, String> param : paramMap.entrySet()) {
jsonObject.put(param.getKey(), param.getValue());
}
StringEntity entity = new StringEntity(jsonObject.toString(), "utf-8");
//设置请求编码
entity.setContentEncoding("utf-8");
//设置数据类型
entity.setContentType("application/json");
httpPost.setEntity(entity);
}
httpPost.setConfig(builderRequestConfig());
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
} catch (Exception e) {
throw e;
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
private static RequestConfig builderRequestConfig() {
return RequestConfig.custom()
.setConnectTimeout(TIMEOUT_MSEC)
.setConnectionRequestTimeout(TIMEOUT_MSEC)
.setSocketTimeout(TIMEOUT_MSEC).build();
}
}
定义一个Location类用来存放地址的经纬度信息
package com.sky.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author : Cookie
* date : 2023/4/20 9:20
* explain :
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Location {
/**
* 纬度值
*/
private double lat;
/**
* 经度值
*/
private double lng;
}
自定义一个工具类,封装对百度接口的请求,方便用于以后在Service层中能够直接的调用 .
注: 因为工具列是自己写的可能会有很多不合适的地方如有发现希望指出
另外其中有的异常类也是自定义如果没有,改为RuntimeException 即可
package com.sky.utils;
import com.sky.entity.Location;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import java.util.HashMap;
/**
* @author : Cookie
* date : 2023/4/19 23:10
* explain :
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@Slf4j
public class BaiduMapUtil {
// 获取配置类中的值
@Value("${sky.baidumap.shop-address}")
private String myShopAddress;
@Value("${sky.baidumap.ak}")
private String ak;
/**
* 获取经纬度
*
* @param userAddress
* @return
*/
public Location getLocation(String userAddress) {
String URL = "https://api.map.baidu.com/geocoding/v3";
HashMap<String, String> map = new HashMap<>();
map.put("address", userAddress);
map.put("output", "json");
map.put("ak", ak);
String body = HttpClientUtil.doGet(URL, map);
Location location = new Location();
try {
JSONObject jsonObject = new JSONObject(body);
// 获取Status
String status = jsonObject.getString("status");
if ("0".equals(status)) {
// 解析JSON
JSONObject res = jsonObject.getJSONObject("result").getJSONObject("location");
// 获取经度
String lng = res.getString("lng");
Double transferLnf = Double.parseDouble(lng);
location.setLng(transferLnf);
// 获取纬度
String lat = res.getString("lat");
Double transferLat = Double.parseDouble(lat);
location.setLat(transferLat);
} else {
// 如果没有返回排除异常交给全局异常处理
throw new RuntimeException("无权限");
}
} catch (Exception e) {
log.info("解析JSON异常,异常信息{}", e.getMessage());
}
return location;
}
/**
* 通过两个经纬度信息判断,返回距离信息
*
* @return 二者的距离
*/
public String getDistance(Location userLocation) {
Location myShopLocation = getLocation(myShopAddress);
// 起始位置, 即我的位置
String origin = myShopLocation.getLat() + "," + myShopLocation.getLng();
// 最终位置, 即终点
String destination = userLocation.getLat() + "," + userLocation.getLng();
String url = "https://api.map.baidu.com/directionlite/v1/riding";
// 发送Get请求
HashMap<String, String> map = new HashMap<>();
map.put("origin", origin);
map.put("destination", destination);
map.put("ak", ak);
map.put("steps_info", "0");
String result = HttpClientUtil.doGet(url, map);
String distance = null;
try {
JSONObject jsonObject = new JSONObject(result);
distance = jsonObject.getJSONObject("result").getJSONArray("routes").getJSONObject(0).getString("distance");
} catch (JSONException e) {
log.info("路径异常");
}
log.info("二者距离{}", distance);
return distance;
}
}
此时就可以通过调用工具类传入userAddress
用户的地址, 因为商家的地址已经配置,此时就可以通过调用getDistance
方法获取到二者的距离.
来源:https://blog.csdn.net/qq_47910339/article/details/130414210
猜你喜欢
- 本文实例为大家分享了java实现捕鱼达人游戏的具体代码,供大家参考,具体内容如下效果图如下:源代码分享:测试类:package game;i
- 今天在码代码的时候突然想到这个问题,觉得有点困惑。在网上也翻阅不少帖子其中有一个帖子给了我一个思路,其实也是解释了基础概念。概念一:try
- 概述从今天开始, 小白我将带大家开启 Java 数据结构 & 算法的新篇章.贪心算法贪心算法 (Greedy Algorithm)
- 本篇文章主要介绍了java自动生成编号的实现,分享给大家,具体如下/** * 自动生成编号格式:yyMM+四位流水号 */ @Reques
- 1、前言随着技术的发展,微信的一系列服务渗透进了我们的生活,但是我们应该怎样进行微信方面的开发呢。相信很多的小伙伴们都很渴望知道吧。这篇文章
- 本文实例为大家分享了SSM实现学生管理系统的具体代码,供大家参考,具体内容如下概述基于Spring + Spring MVC 的学生管理系统
- public final class Integer extends Number implements Comparable<Int
- java 反射机制:测试实体类以Human为例/** * Project: Day12_for_lxy * Created: Lulu *
- Android Build类的详解及简单实例一、类结构:java.lang.Object? android.os.Build二、类概述:从系
- 概况本文主要给大家介绍了通过JDK源码学习InputStream的相关内容,JDK 给我们提供了很多实用的输入流 xxxInputStrea
- 一、为什么要控制当你在项目启动时需要提前做一个业务的初始化工作时,或者你正在开发某个中间件需要完成自动装配时。你会声明自己的Configur
- Mybatis入门-基于配置实现单表的增删改查Mybatis简介官网链接:https://mybatis.org/mybatis-3/zh/
- 一. 前言最近我发现了一个事情,那就是在面试笔试中,好多公司都喜欢在String字符串上出问题,涉及到方方面面的知识,包括其中的一些常用方法
- 最近在搭建springmvc的框架,遇到的这样的问题:在地址栏访问登陆界面访问不了,http://localhost/XXXX/WEB-IN
- 使用Myeclipse搭建maven项目准备工作安装maven官网下载安装(http://maven.apache.org/)配置环境变量配
- Bean的自动装配自动装配说明自动装配是使用spring满足bean依赖的一种方法spring会在应用上下文中为某个bean寻找其依赖的be
- Spring depends-on的使用通过在XML中的<bean>里配置depends-on属性或者在一个类上使用注解@Dep
- 简介Springboot Admin是一个管理和监控Springboot项目的组件,分为服务端和客户端,两端通过http进行通信。由于其轻量
- public static boolean isMobileNumber(String mobiles) {return Pattern.c
- 1.editplus1.1 官方下载https://www.editplus.com/官方下载最新的64位2 .解压就可以使用2.1 vsc