Springboot 微信小程序定位后将坐标转换为百度地图坐标,在百度地图做逆地址解析

问题解析以及解决思路

业务:微信小程序定位后,将坐标转换为百度地图坐标,在百度地图做逆地址解析

问题:微信小程序的定位是拿的腾讯地图的经纬度,但是我们app端这边使用的百度地图,如果直接使用腾讯地图的经纬度再使用腾讯地图的逆地址解析需要腾讯和百度商业授权,为了减少授权成本

解决方案:将腾讯地图的经纬度转换为百度地图的经纬度后,再进行逆地址解析

  • 腾讯地图转百度地图此处有两种解决方案
    • 使用数学的方式进行转换可参考我的这篇文章微信小程序定位判断点位是否在某个范围内(腾讯地图转百度地图),但是这种方法有会导致定位有偏差,如果对定位精度要求高的需求不建议使用
    • 使用百度地图的官方接口进行转换(我相信官方的转换精度肯定会高一些,本文使用)

本文使用到的两个百度地图的接口文档如下

坐标转换

全球逆地理编码

解决方案实现

开通百度地图相关接口权限

Springboot对接接口

  1. 新增接口相关的配置
baidu:service: # 服务端应用appId: 1160xxxxxapiKey: C8NCMTxxxxxxxxxxxxxxxxxxx
  1. 百度接口统一返回对象封装
import lombok.Data;@Data
public class BaiduApiResponse<T> {private int status;private T result;
}
  1. 坐标转换返回对象封装
import lombok.Data;import java.util.List;@Data
public class GeoConvResponseDto {private double x;private double y;}
  1. 全球逆地理编码返回对象封装
import lombok.Data;import java.util.List;@Data
public class ReverseGeocodingResponseDto {private Location location;private String formatted_address;private Edz edz;private String business;private AddressComponent addressComponent;private List<Object> pois;private List<Object> roads;private List<Object> poiRegions;private String sematic_description;private String formatted_address_poi;private int cityCode;@Datapublic static class Location {private double lng;private double lat;}@Datapublic static class Edz {private String name;}@Datapublic static class AddressComponent {private String country;private int country_code;private String country_code_iso;private String country_code_iso2;private String province;private String city;private int city_level;private String district;private String town;private String town_code;private String adcode;private String street;private String street_number;}
}
  1. 点位对象封装
import lombok.AllArgsConstructor;
import lombok.Data;@Data
@AllArgsConstructor
public class CoordinateDto {private double longitude;private double latitude;@Overridepublic String toString() {return longitude + "," + latitude;}
}
  1. BaiduMapService(方法实现)
  • requestGeoConv参数解释
    • coords: 需转换的源坐标,多组坐标以“;”我这里使用的coordinate对象重新了toString方法来构造接口参数
    • ak: 开发者密钥, 申请AK
    • model:
      • 转换方式可选值(默认值 1):
        1:amap/tencent to bd09ll
        2:gps to bd09ll
        3:bd09ll to bd09mc
        4:bd09mc to bd09ll
        5:bd09ll to amap/tencent
        6:bd09mc to amap/tencent
  • requestReverseGeocoding 参数解释
    • location: 根据经纬度坐标获取地址。(请注意这里是反过来的38.76623,116.43213lat<纬度>,lng<经度>)
    • ak: 开发者密钥, 申请AK
    • coordtype: 传入的坐标类型,目前支持的坐标类型包括:bd09ll(百度经纬度坐标)、bd09mc(百度米制坐标)、gcj02ll(国测局经纬度坐标,仅限中国)、wgs84ll( GPS经纬度)坐标系说明
      • 因为requestGeoConv方法已经给我们将经纬度转换为bd09ll标准了,所以我写死为bd09ll
    • extensions_poi: extensions_poi=0,不召回pois数据。
      extensions_poi=1,返回pois数据(默认显示周边1000米内的poi),并返回sematic_description语义化数据。
package com.applets.manager.core.service;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.applets.manager.core.exception.BusinessException;
import com.applets.manager.core.model.dto.BaiduApiResponse;
import com.applets.manager.core.model.dto.CoordinateDto;
import com.applets.manager.core.model.dto.GeoConvResponseDto;
import com.applets.manager.core.model.dto.ReverseGeocodingResponseDto;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriUtils;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;@Slf4j
@Service
public class BaiduMapService {private static final String GEO_CONV_URL = "https://api.map.baidu.com/geoconv/v2/?";private static final String REVERSE_GEOCODING_URL = "https://api.map.baidu.com/reverse_geocoding/v3?";@Value("${baidu.service.appId}")private String appId;@Value("${baidu.service.apiKey}")private String apiKey;/*** 发送请求到百度地图 API,执行坐标转换** @param coordinate  点位对象,即经纬度对象* @param model  转换模型* @return API 响应结果* @throws Exception*/public BaiduApiResponse<List<GeoConvResponseDto>> requestGeoConv(CoordinateDto coordinate, String model) throws Exception {Map<String, String> params = new LinkedHashMap<>();params.put("coords", coordinate.toString());params.put("model", model);params.put("ak", apiKey);String res = sendGetRequest(GEO_CONV_URL, params);BaiduApiResponse<List<GeoConvResponseDto>> response = null;if (StringUtils.isNotEmpty(res)){response = JSON.parseObject(res, new TypeReference<BaiduApiResponse<List<GeoConvResponseDto>>>() {});if (0 != response.getStatus()){log.info("坐标转换结果:{}", response);throw new BusinessException("百度接口请求错误:"+response.getResult());}}return response;}/*** 发送请求到百度地图 API,执行逆地理编码** @param coordinate  点位对象,即经纬度对象* @return API 响应结果* @throws Exception*/public BaiduApiResponse<ReverseGeocodingResponseDto> requestReverseGeocoding(CoordinateDto coordinate) throws Exception {Map<String, String> params = new LinkedHashMap<>();params.put("ak", apiKey);params.put("output", "json");params.put("coordtype", "bd09ll");params.put("extensions_poi", "0");params.put("location", coordinate.getLatitude()+","+coordinate.getLongitude());String res = sendGetRequest(REVERSE_GEOCODING_URL, params);BaiduApiResponse<ReverseGeocodingResponseDto> response = null;if (StringUtils.isNotEmpty(res)){response = JSON.parseObject(res, new TypeReference<BaiduApiResponse<ReverseGeocodingResponseDto>>() {});if (0 != response.getStatus()){log.info("坐标转换结果:{}", response);throw new BusinessException("百度接口请求错误:"+response.getResult());}}return response;}/*** 通用的 GET 请求方法** @param strUrl API URL* @param param 请求参数* @return 响应字符串* @throws Exception*/private String sendGetRequest(String strUrl, Map<String, String> param) throws Exception {if (strUrl == null || strUrl.isEmpty() || param == null || param.isEmpty()) {throw new IllegalArgumentException("URL 和参数不能为空");}StringBuilder queryString = new StringBuilder(strUrl);for (Map.Entry<String, String> entry : param.entrySet()) {queryString.append(entry.getKey()).append("=").append(UriUtils.encode(entry.getValue(), "UTF-8")).append("&");}// 删除最后一个 '&' 字符queryString.deleteCharAt(queryString.length() - 1);URL url = new URL(queryString.toString());HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();httpConnection.connect();try (InputStreamReader isr = new InputStreamReader(httpConnection.getInputStream());BufferedReader reader = new BufferedReader(isr)) {StringBuilder response = new StringBuilder();String line;while ((line = reader.readLine()) != null) {response.append(line);}log.info("BaiduMapService.sendGetRequest.response:{}",response.toString());return response.toString();}}}

测试

import com.alibaba.fastjson.JSON;
import com.applets.manager.api.StartApplication;
import com.applets.manager.core.model.dto.BaiduApiResponse;
import com.applets.manager.core.model.dto.CoordinateDto;
import com.applets.manager.core.model.dto.GeoConvResponseDto;
import com.applets.manager.core.model.dto.ReverseGeocodingResponseDto;
import com.applets.manager.core.service.BaiduMapService;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.geotools.referencing.GeodeticCalculator;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
import java.util.stream.Collectors;
import org.springframework.web.util.UriUtils;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;/*** @author zr 2024/4/17*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = StartApplication.class)
@Slf4j
public class BaiduMapTest {@Autowiredprivate BaiduMapService baiduMapService;@Testpublic void requestGeoConv() {try {BaiduApiResponse<List<GeoConvResponseDto>> geoConvResponseDtoBaiduApiResponse = baiduMapService.requestGeoConv(new CoordinateDto(103.979967,30.990777), "1");log.info("requestGeoConv: " + JSON.toJSONString(geoConvResponseDtoBaiduApiResponse));} catch (Exception e) {throw new RuntimeException(e);}}@Testpublic void requestReverseGeocoding() {try {BaiduApiResponse<ReverseGeocodingResponseDto> response = baiduMapService.requestReverseGeocoding(new CoordinateDto(103.98657912268618,30.996470768223653));log.info("requestReverseGeocoding: " + JSON.toJSONString(response));} catch (Exception e) {throw new RuntimeException(e);}}
}

坐标转换测试

初始点位是我随便再腾讯地图上找的点位

注意:这里百度地图返回的地址是一个list

全球逆地理编码测试

使用第一步转换的结果进行逆地址解析

返回json实例

{"result":{"addressComponent":{"adcode":"510182","city":"成都市","city_level":2,"country":"中国","country_code":0,"country_code_iso":"CHN","country_code_iso2":"CN","district":"彭州市","province":"四川省","street":"什彭路","street_number":"","town":"天彭街道","town_code":"510182001"},"business":"","cityCode":75,"edz":{"name":""},"formatted_address":"四川省成都市彭州市什彭路","formatted_address_poi":"","location":{"lat":30.99647061454463,"lng":103.98657912268614},"poiRegions":[],"pois":[],"roads":[],"sematic_description":""},"status":0}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/60930.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python爬虫----python爬虫基础

一、python爬虫基础-爬虫简介 1、现实生活中实际爬虫有哪些&#xff1f; 2、什么是网络爬虫&#xff1f; 3、什么是通用爬虫和聚焦爬虫&#xff1f; 4、为什么要用python写爬虫程序 5、环境和工具 二、python爬虫基础-http协议和chrome抓包工具 1、什么是http和https协议…

人力资源招聘系统-提升招聘效率与质量的关键工具

在当今这个竞争激烈的商业环境中&#xff0c;企业要想在市场中立于不败之地&#xff0c;关键在于拥有高素质的人才队伍。然而&#xff0c;传统的招聘方式往往效率低下&#xff0c;难以精准匹配企业需求与人才特质&#xff0c;这无疑给企业的发展带来了不小的挑战。 随着科技的飞…

Python3.11.9+selenium,获取图片验证码以及输入验证码数字

Python3.11.9+selenium,获取图片验证码以及输入验证码数字 1、遇到问题:登录或修改密码需要验证码 2、解决办法: 2.1、安装ddddocr pip install ddddocr 2.2、解析验证码函数 import ddddocr def get_capcha_text():#获取验证码图片ele_pic = driver.find_element(By.XPAT…

2024-11-16-机器学习方法:无监督学习(1) 聚类(上)

文章目录 机器学习方法&#xff1a;无监督学习&#xff08;1&#xff09; 聚类&#xff08;上&#xff09;1. 聚类的基本概念1.1 聚类的概念1.2 聚类的功能1.3 聚类的算法 2. 相似度或距离2.1 闵可夫斯基距离2.2 相关系数2.3 夹角余弦 3 类或簇3.1 类的特征 4 类与类之间的距离…

Ubuntu 系统端口查询与管理详细分析

目录 前言1. 查询端口占用情况2. 释放占用的端口3. 修改应用程序的端口 前言 Window的端口被占用&#xff0c;类似的知识点&#xff1a;重装mysql时3306端口被占用解决方法 事情起因是宝塔的CPU负载过大&#xff0c;重启服务进程之后还是爆&#xff0c;后续发现是端口被占用&…

go 集成swagger 在线接口文档

安装swaggo go install github.com/swaggo/swag/cmd/swaglatest 编写swag import ("github.com/gin-gonic/gin""goWeb/internal/service""goWeb/model/response" )// UserRouter 路由 func UserRouter(ctx *gin.RouterGroup) {ctx.GET("/…

蓝桥杯每日真题 - 第15天

题目&#xff1a;&#xff08;钟表&#xff09; 题目描述&#xff08;13届 C&C B组B题&#xff09; 解题思路&#xff1a; 理解钟表指针的运动&#xff1a; 秒针每分钟转一圈&#xff0c;即每秒转6度。 分针每小时转一圈&#xff0c;即每分钟转6度。 时针每12小时转一圈…

Redis性能优化——针对实习面试

目录 Redis性能优化什么是bigkey&#xff1f;bigkey的危害&#xff1f;如何处理bigkey?什么是hotkey&#xff1f;hotkey的危害&#xff1f;如何处理hotkey&#xff1f;如何处理大量key集中过期问题&#xff1f;什么是内存碎片&#xff1f;为什么会有Redis内存碎片&#xff1f;…

小白进!QMK 键盘新手入门指南

经常玩键盘的伙伴应该都知道&#xff0c;现在的键盘市场可谓是百花齐放&#xff0c;已经不是之前的单一功能产品化时代。我们可以看到很多诸如&#xff1a;机械轴键盘、磁轴键盘、光轴键盘、电感轴键盘&#xff0c;以及可能会上市的光磁轴键盘&#xff0c;更有支持屏幕的、带旋…

分布式事务seata基于docker安装和项目集成seata

目录 本地事务 根据隔离性的等级会导致不同的问题 有四种隔离等级 分布式事务 现在有一个场景&#xff1a; 结果&#xff1a; CAP定理 矛盾 总结&#xff1a; es集群使用的是cp: BASE理论 解决分布式事务的思路 Seata Seata的架构 docker安装seata 1.拉取seat…

【Qt实现虚拟键盘】

Qt实现虚拟键盘 &#x1f31f;项目分析&#x1f31f;实现方式&#x1f31f;开发流程 &#x1f31f;项目分析 需求&#xff1a;为Linux环境下提供可便捷使用的虚拟键盘OS环境&#xff1a;Windows 7/11、CentOS 7开发语言&#xff1a;Qt/C IDE&#xff1a;QtCreator 、Qt5.14.2功…

react中如何在一张图片上加一个灰色蒙层,并添加事件?

最终效果&#xff1a; 实现原理&#xff1a; 移动到图片上的时候&#xff0c;给img加一个伪类 &#xff01;&#xff01;此时就要地方要注意了&#xff0c;因为img标签是闭合的标签&#xff0c;无法直接添加 伪类&#xff08;::after&#xff09;&#xff0c;所以 我是在img外…

电子应用产品设计方案-11:全自动智能全屋智能系统设计方案

一、设计目标 打造便捷、舒适、安全且节能的全屋智能环境。 二、系统组成 1. 智能灯光系统 - 在客厅、卧室、厨房、卫生间等各处安装智能灯具&#xff0c;可通过手机 APP、语音控制实现开关、调光调色。如客厅设置多种场景模式&#xff0c;如“观影模式”&#xff08;灯光…

服务端高并发分布式结构进阶之路

序言 在技术求知的旅途中&#xff0c;鉴于多数读者缺乏在中大型系统实践中的亲身体验&#xff0c;难以从宏观角度把握某些概念&#xff0c;因此&#xff0c;本文特选取“电子商务应用”作为实例&#xff0c;详细阐述从百级至千万级并发场景下服务端架构的逐步演变历程。同时&am…

WebRTC视频 02 - 视频采集类 VideoCaptureModule

WebRTC视频 01 - 视频采集整体架构 WebRTC视频 02 - 视频采集类 VideoCaptureModule&#xff08;本文&#xff09; WebRTC视频 03 - 视频采集类 VideoCaptureDS 上篇 WebRTC视频 04 - 视频采集类 VideoCaptureDS 中篇 WebRTC视频 05 - 视频采集类 VideoCaptureDS 下篇 一、前言…

POI实现根据PPTX模板渲染PPT

目录 1、前言 2、了解pptx文件结构 3、POI组件 3.1、引入依赖 3.2、常见的类 3.3、实现原理 3.4、关键代码片段 3.4.1、获取ppt实例 3.4.2、获取每页幻灯片 3.4.3、循环遍历幻灯片处理 3.4.3.1、文本 3.4.3.2、饼图 3.4.3.3、柱状图 3.4.3.4、表格 3.4.3.5、本地…

sqli-labs靶场17-20关(每日四关)持续更新!!!

Less-17 打开靶场&#xff0c;发现页面比之前多了一行字 翻译过来就是&#xff0c;密码重置&#xff0c;大家肯定会想到&#xff0c;自己平时在日常生活中怎么密码重置&#xff0c;肯定是输入自己的用户名&#xff0c;输入旧密码&#xff0c;输入新密码就可以了&#xff0c;但…

node.js下载安装步骤整理

>> 进入node.js下载页面下载 | Node.js 中文网 >>点击 全部安装包 >>删除网址node后面部分&#xff0c;只保留如图所示部分&#xff0c;回车 >>点击进入v11.0.0/版本 >>点击下载node-v11.0.0-win-x64.zip(电脑是windows 64位操作系统适用) >…

ThinkServer SR658H V2服务器BMC做raid与装系统

目录 前提准备 一. 给磁盘做raid 二. 安装系统 前提准备 磁盘和系统BMC地址都已经准备好&#xff0c;可正常使用。 例&#xff1a; 设备BMC地址&#xff1a;10.99.240.196 一. 给磁盘做raid 要求&#xff1a; 1. 将两个894G的磁盘做成raid1 2. 将两块14902G的磁盘各自做…

SpringBoot配置类

在Spring Boot中&#xff0c;配置类是一种特殊的类&#xff0c;用于定义和配置Spring应用程序的各种组件、服务和属性。这些配置类通常使用Java注解来声明&#xff0c;并且可以通过Spring的依赖注入机制来管理和使用。 Spring 容器初始化时会加载被Component、Service、Reposi…