Java坐标转换的多元实现路径:在线调用、百度与高德地图API集成及纯Java代码实现

目录

前言

一、直接在线调用

1、超图在线转换器

2、ToolGen在线转换

3、蛙蛙工具在线转换

二、在线API调用

1、百度API说明

2、百度API定义

3、高德API说明

4、高德API定义

5、调用成果展示

三、纯Java本地离线计算

1、本地计算组件介绍

2、调用实例

四、不同实现方式对比

五、总结


前言

在当今数字化时代,地理信息系统(GIS)与各类位置服务已深度融入我们的生活与工作。从精准的物流配送到个性化旅游路线规划,从城市规划到环境监测,坐标转换作为连接现实地理空间与数字地图空间的关键技术,其重要性不言而喻。在实际应用中,开发者常常面临多种坐标系之间的转换需求。例如,将GPS设备采集的经纬度坐标(通常基于WGS-84坐标系)转换为国内地图服务常用的火星坐标系(GCJ-02),或者进一步转换为百度地图的BD-09坐标系,以实现精准的地图展示与位置服务。这些坐标系之间的差异,源于不同的地理模型、投影方式以及政策要求,而准确的坐标转换则是确保位置信息准确无误的关键。

Java实现坐标转换的路径主要分为三大类:直接在线调用、百度与高德地图API集成以及纯Java代码实现。每一种方式都有其独特的应用场景、优势与局限性。本文详细介绍这三种不同的应用模式,通过后续的内容,您不仅可以学习不同的坐标转换方法,同时还可以对比不同的实现方法的结果。随着技术的不断进步,Java在坐标转换领域的应用也在持续拓展与深化。开发者可以根据具体项目需求、资源条件以及对性能、成本、安全等多方面因素的综合考量,选择最适合的坐标转换实现路径。无论是借助外部在线服务的便捷性,还是利用地图API的强大功能,亦或是通过纯Java代码实现的自主可控,Java都以其强大的语言特性、丰富的类库支持以及庞大的开发者社区,为坐标转换任务提供了坚实的编程基础与无限的可能性。

一、直接在线调用

直接在线调用方式,通过调用网络上的坐标转换服务,如一些专业的GIS服务平台提供的API接口,开发者无需深入了解复杂的坐标转换算法,只需将待转换的坐标发送请求,即可获得转换后的结果。这种方式简单便捷,尤其适合一些对坐标转换精度要求不高、数据量较小且对实时性要求不苛刻的场景,如简单的地理信息查询、小规模的地图标注等。然而,其依赖网络连接,一旦网络状况不佳或服务提供商出现问题,将直接影响应用的可用性。此外,频繁调用外部服务可能产生额外成本,且数据安全性与隐私性也需谨慎考量。本节将分享三个可以直接在网页端进行直接使用的在线转换器,这种方式适用于初级用户,无任何代码能力,也不想去深入学习编程知识,对于坐标的数量要求不多。如果您目前是这种方式,那么直接接入在线调用的能力,无疑是提高开发效率的优良姿势。为了统一对比转换后的坐标值,这里我们采用一个WGS84的坐标,坐标值为:

java 复制代码
double lng = 112.86746750941569;
double lat = 28.195681037862602;

为了保证对统一的转换结果进行对比,这里我们均使用WGS84坐标转换到高德的GCJ02坐标。

1、超图在线转换器

首先我们可以使用超图的在线转换来进行测试,测试地址:超图在线坐标转换。在浏览器中输入上面的访问地址后,可以看到如下界面:

在输入界面中可以看到有多种输入方式,可以将坐标进行手动输入,也可以使用文件导入。在输入栏的坐标输入多行文本框中输入坐标,同时需要选择输入坐标系和输出坐标系,点击转换按钮即可实现转换。可以看到使用超图的在线坐标转换器得到的转换坐标值如下:

bash 复制代码
112.87288460963879,28.192167006413552

需要注意的是,在使用超图的在线坐标转换中,一次性输入的坐标数量是有限的,不超过100个,如果有批量坐标转换,需要按100进行拆分。

2、ToolGen在线转换

介绍完超图的在线工具,接下来介绍另外一个在线工具,ToolGen:ToolGen工具,在浏览器中输入访问地址后可以看到以下界面:

可以看到,ToolGen工具除了提供坐标转换外,还有很多其它的功能。不仅如此,对于坐标的转换服务,ToolGen是不仅提供单个坐标的转换,也提供了多个坐标的转换。同样的操作,在页面中输入原坐标后,并且选择原坐标系、原坐标格式(经度在前还是在后)后进行坐标转换,可以在右边看到转换结果。同样可以看到,使用在线转换后,对应的坐标结果如下:

bash 复制代码
112.87288460963879,28.192167006413552

这两个值很有意思,基本跟超图的转换结果一致。

3、蛙蛙工具在线转换

最后来看一下蛙蛙工具的在线转换功能,访问地址:蛙蛙工具。在浏览器中输入访问地址后展示以下界面:

同理,我们输入转换的WGS84坐标,然后期望转换到GCJ02坐标,坐标输入完成后,点击马上转换按钮,在下面的表格中得到转换结果。

bash 复制代码
112.87288460963879,28.192167006413552

可以看到,使用在线网页转换工具得到的转换坐标都是一样的。大概率他们使用的方法一致。

二、在线API调用

除了使用在线工具转换外,我们还可以使用在线WebAPI的方式进行集成调用。百度地图和高德地图作为国内领先的地图服务提供商,其API接口涵盖了丰富的地理信息处理功能,包括但不限于坐标转换。通过集成这些API,开发者可以轻松实现WGS-84到GCJ-02再到BD-09或高德自有的坐标系转换,同时还能获取地图渲染、路径规划、周边搜索等增值服务。这种方式适用于对地图功能依赖度高、需要与地图服务深度整合的应用场景,如出行导航、外卖配送、智能交通等领域。其优势在于数据的准确性和实时性有保障,且经过大量用户验证,稳定性较强。不过,使用这些API通常需要遵循相应的使用规范和限制,如调用频率限制、数据使用范围等,且在某些特殊情况下,如地图服务提供商的政策调整或接口变更,可能需要开发者及时调整代码以保证应用的正常运行。下面我们将对这两种实现方式进行实际调用说明。

1、百度API说明

请求参数

参数名称 含义 类型 举例 默认值 是否必须
coords 需转换的源坐标,多组坐标以";"分隔 (经度,纬度) string 114.21892734521,29.575429778924
ak 开发者密钥, 申请AK string
model 转换方式可选值: 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 int 1 1
sn 若用户所用AK的校验方式为SN校验时该参数必须sn生成 string
output 返回结果格式 string json json

返回参数

名称 类型 说明
status int 本次API访问状态,如果成功返回0,如果失败返回其他数字
result json或者xml数组 转换结果
x float 经度
y float 纬度

2、百度API定义

这里我们以UniHttp框架为例,重点讲解如何在Java中实现百度API的调用。首先需要定义个第三方访问接口,用于代理百度API的访问方法,核心代码如下:

java 复制代码
package com.yelang.project.thridinterface;
import com.burukeyou.uniapi.http.annotation.HttpApi;
import com.burukeyou.uniapi.http.annotation.param.QueryPar;
import com.burukeyou.uniapi.http.annotation.request.GetHttpInterface;
import com.burukeyou.uniapi.http.core.response.HttpResponse;
/**
 * - 百度坐标转换接口
 * @author 夜郎king
 */
@HttpApi(url = "https://api.map.baidu.com/geoconv/v2")
public interface BaiduGeoConvertService {

	/**
	 * 
	 * @param coords 需转换的源坐标,多组坐标以";"分隔(经度,纬度)
	 * @param model 转换方式可选值:
		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
	 * @param output 返回结果格式 json
	 * @param ak 开发者密钥, 申请AK
	 * @return
	 */
	@GetHttpInterface("/")
	public HttpResponse<String> convert(@QueryPar("coords") String coords, @QueryPar("model") int model,
			@QueryPar("output") String output, @QueryPar("ak") String ak);
}

3、高德API说明

同样的我们也对高德的坐标转换API进行简单介绍,首先先来看一下它的官方网站说明。

请求参数

|-----------|----------|------------------------------------------------------------------------------------|------|----------|
| 参数名 | 含义 | 规则说明 | 是否必须 | 缺省值 |
| key | 请求服务权限标识 | 用户在高德地图官网 申请 Web 服务 API 类型 KEY | 必填 | 无 |
| locations | 坐标点 | 经度和纬度用","分割,经度在前,纬度在后,经纬度小数点后不得超过6位。多个坐标对之间用"|"进行分隔最多支持40对坐标。 | 必填 | 无 |
| coordsys | 原坐标系 | 可选值: gps; mapbar; baidu; autonavi(不进行转换) | 可选 | autonavi |
| sig | 数字签名 | 数字签名获取和使用方法 | 可选 | 无 |
| output | 返回数据格式类型 | 可选值:JSON,XML | 可选 | JSON |

返回结果参数说明

坐标转换的响应结果的格式由请求参数 output 指定。

|-----------|------------------------------|------------------------------------------------------------------------------------------------------------------|
| 名称 | 含义 | 规则说明 |
| status | 返回状态 | 值为0或1 1:成功;0:失败 |
| info | 返回的状态信息 | status 为0时,info 返回错误原;否则返回"OK"。详情参阅 info 状态表 |
| locations | 转换之后的坐标。若有多个坐标,则用 ";"进行区分和间隔 | |

4、高德API定义

与百度API定义一致,我们也需要为高德API创建一个第三方接口,用来进行请求的实际发送。核心代码如下:

java 复制代码
package com.yelang.project.thridinterface;
import com.burukeyou.uniapi.http.annotation.HttpApi;
import com.burukeyou.uniapi.http.annotation.param.QueryPar;
import com.burukeyou.uniapi.http.annotation.request.GetHttpInterface;
import com.burukeyou.uniapi.http.core.response.HttpResponse;
/**
 * - 高德地图坐标转换服务
 * @author 夜郎king
 *
 */
@HttpApi(url = "https://restapi.amap.com/v3/assistant/coordinate")
public interface AmapGeoConvertService {
	/**
	 * @param locations 坐标点,经度和纬度用","分割,经度在前,纬度在后,经纬度小数点后不得超过6位。多个坐标对之间用"|"进行分隔最多支持40对坐标。
	 * @param coordsys 原坐标系 可选值:
						gps;
						mapbar;
						baidu;
						autonavi(不进行转换)
	 * @param output 返回数据格式类型 可选值:JSON,XML
	 * @param key 请求服务权限标识
	 * @return
	 */
	@GetHttpInterface("/convert")
	public HttpResponse<String> convert(@QueryPar("locations") String locations, @QueryPar("coordsys") String coordsys,
			@QueryPar("output") String output, @QueryPar("key") String key);
}

5、调用成果展示

本节将主要进行接口的调用,需要注意的是在百度接口中,暂时无直接将WGS84直接转GCJ02坐标的方法,先将坐标转换位bd的坐标,然后再转成高德的GCJ02。调用代码如下:

java 复制代码
package com.yelang.project.unihttp;
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 com.burukeyou.uniapi.http.core.response.HttpResponse;
import com.yelang.common.utils.geo.CoordinateTransformUtil;
import com.yelang.project.thridinterface.AmapGeoConvertService;
import com.yelang.project.thridinterface.BaiduGeoConvertService;
@SpringBootTest
@RunWith(SpringRunner.class)
public class GeoConvertCase {
	/**
	 * - 高德地图ak值
	 */
	private static final String AMAP_CLIENT_AK = "amap_key";
	/**
	 *- 百度地图ak值
	 */
	private static final String BAIDU_CLIENT_AK = "baidu_key";
	@Autowired
	private BaiduGeoConvertService baiduService;
	@Autowired
	private AmapGeoConvertService amapService;
	@Test
	public void gps2amap() {
		double lng = 112.86746750941569;
		double lat = 28.195681037862602;
		HttpResponse<String> amapResult = amapService.convert(lng+"," + lat, "gps", "json", AMAP_CLIENT_AK);
		System.out.println("高德接口转换结果:"+amapResult.getBodyResult());
		HttpResponse<String> baiduResult = baiduService.convert(lng+"," + lat, 2, "json", BAIDU_CLIENT_AK);
		System.out.println("百度接口gps转bd09ll结果:"+baiduResult.getBodyResult());
		//百度接口gps转bd09ll结果:{"status":0,"result":[{"x":112.87944784161859,"y":28.197904908162568}]}
		baiduResult = baiduService.convert("112.87944784161859,28.197904908162568", 5, "json", BAIDU_CLIENT_AK);
		System.out.println("百度接口bd09ll转amap结果:"+baiduResult.getBodyResult());
	}
}

在IDE中运行以上程序后,在应用的控制台可以看到如下输出:

bash 复制代码
高德接口转换结果:{"status":"1","info":"ok","infocode":"10000","locations":"112.872886284723,28.192168240018"}
百度接口gps转bd09ll结果:{"status":0,"result":[{"x":112.87944784161859,"y":28.197904908162568}]}
百度接口bd09ll转amap结果:{"status":0,"result":[{"x":112.87288994895299,"y":28.192170638654287}]}

可以比较直观的看到,与之前的在线转换不同,高德地图和百度地图的生成结果还是存在不同的。但是如果仅对比前面的位数,很多都是相同的。

三、纯Java本地离线计算

Java作为一种广泛应用于企业级开发、大数据处理以及各类复杂系统构建的编程语言,为坐标转换提供了多种高效、灵活的实现方式,满足不同场景下的多样化需求。纯Java代码实现坐标转换则为开发者提供了最大的自主性与灵活性。这种方式要求开发者深入理解坐标转换的数学原理,如椭球模型、投影变换公式等,并通过Java语言将其转化为可执行的代码逻辑。虽然实现过程较为复杂,需要投入较多的时间和精力进行算法研究、代码调试与优化,但它不受外部服务提供商的限制,可完全根据自身需求定制转换逻辑,适用于对坐标转换精度要求极高、数据量大且对数据安全与隐私性有严格要求的场景,如军事测绘、高精度地理科学研究等。此外,纯Java实现还可以作为离线解决方案,不依赖网络连接,可在无网络环境或网络受限的特殊场景下使用。

1、本地计算组件介绍

其实最早在之前的博客中对如何使用Java实现本地的转换转换,这样就可以不受API调用次数的限制。这里还是再次简单介绍基于Java的本地离线计算组件:实现的Java版本

2、调用实例

同样的,为了更好的进行坐标转换成果进行对比,我们也需要使用本地调用的模式对结果进行展示。调用实例代码如下:

java 复制代码
double lng = 112.86746750941569;
double lat = 28.195681037862602;
double [] gcj02 = CoordinateTransformUtil.wgs84togcj02(lng, lat);
System.out.println("本地离线转换:" +  gcj02[0] + "==" + gcj02[1]);

程序运行后,在控制台可以看到如下输出:

bash 复制代码
本地离线转换:112.87288460963879==28.192167006413552

请问大家注意到什么了吗?这里的坐标跟在线转换工具的结果是完全一致的,是否大家参考的都是同一份呢。

四、不同实现方式对比

下面根据不同的集成方式和效率以及成果精度等方面进行简单对比,如果您在进行技术选型,可以进行参考:

|--------|--------------------------------------|------------------------------------------------------------------------------------|---------------------------------------|
| | 在线调用 | WebAPI | 本地集成 |
| 学习成本 | 低 | 中 | 高 |
| 代码能力要求 | 低 | 中 | 高 |
| 网络依赖 | 强 | 强 | 低 |
| 坐标持类型 | 低 | 较多 | 低 |
| 坐标数 | 有的有限制,比如100/次 | 有限制 | 无 |
| 成果对比 | 12.87288460963879 28.192167006413552 | 高德:(112.872886284723, 28.192168240018) 百度:(112.87288994895299, 28.192170638654287) | 112.87288460963879 28.192167006413552 |

通过对比可以看到,从结果来看,在线转换跟本地集成的转换成果几乎一致。而百度和高德地图的转换结果,经度前5位(含小数点)是完全一致的,纬度前4位(含小数点)完全一致。

五、总结

以上就是本文的主要内容,Java实现坐标转换的路径主要分为三大类:直接在线调用、百度与高德地图API集成以及纯Java代码实现。每一种方式都有其独特的应用场景、优势与局限性。本文详细介绍这三种不同的应用模式,通过具体内容的讲解,您不仅可以学习不同的坐标转换方法,同时还可以对比不同的实现方法的结果。无论是借助外部在线服务的便捷性,还是利用地图API的强大功能,亦或是通过纯Java代码实现的自主可控,Java都以其强大的语言特性、丰富的类库支持以及庞大的开发者社区,为坐标转换任务提供了坚实的编程基础与无限的可能性。行文仓促,定有不足之处,欢迎各位朋友在评论区批评指正,不胜感激。