目录

  • 1 背景说明
    • 1.1 空间数据
    • 1.2 CGCS2000
    • 1.3 WGS84
    • 1.4 BD09
  • 2 读取数据库中的geometry数据
  • 3 代码实现
    • 3.1 CGCS2000转WGS84
    • 3.2 BD09坐标系中点的表示
    • 3.3 WGS84转BD09
    • 3.4测试结果
  • 4 依赖和环境
  • 5 提示
  • 6 结语

1 背景说明

最近的项目中涉及到空间数据的转换,主要是把CGCS200坐标转换为WGS84坐标和BD09坐标。我在网上找了许久,只找到了WGS84坐标转BD09坐标的工具类,但没有找到CGCS200转换到WGS84坐标的工具类。我实在没有办法,就只有自己写。但我没有GIS行业的教育背景,不了解坐标转换的专业知识,不过我断定GIS行业一定有现成的相关方法。通过查阅相关资料,最后在ArcGIS提供的 ArcGIS Runtime API for Java中找到了相关API。我借此实现了个工具类,测试效果也还不错。现在写出这篇文章,共享我的代码,希望能帮到有同样问题的开发者。
为了方便GIS行业外的朋友更流畅地阅读本文,先阐释下相关名词概念。

1.1 空间数据

从数据库的角度来看,是指在表中以geometry类型存在的数据。
从java语言的角度来看,是指com.esri.arcgisruntime.geometry包下各种类的对象,包括Point、Multipoint、Polyline、Polygon等等.

1.2 CGCS2000

CGCS2000:China Geodetic Coordinate System 2000,2000国家大地坐标系,是我国当前最新的国家大地坐标系。该坐标系在ArcGIS中有众多子坐标系。如下图所示。本文选用的是CGCS2000_3_Degree_GK_CM_105E。下方的坐标系详情中有WKID,您需要记录下这个值,后续会用到。

1.3 WGS84

WGS84:World Geodetic System 1984,是为GPS全球定位系统使用而建立的坐标系统,在全球有广泛的使用。

1.4 BD09

BD09:百度地图坐标系,它是在标准Web墨卡托的基础上进行GCJ-02加偏之后,再加上百度自身的加偏算法。

2 读取数据库中的geometry数据

我采用的方式是在数据库用SQL语句查询出geometry字段的String表达形式,再做后续处理。代码片段如下:

@Query( value = "select SHAPE.STAsText() FROM LAND WHERE ID=?", nativeQuery = true)
String  getShapeString (String id);

下面这个字符串是本文通过此方法在数据库中查询出来的,此字符串表示一个地块的坐标,逗号分隔出每个坐标点,多个坐标点连成一个面。(此数据是测试数据,由笔者随意编造,没有描述任何真实意义)

POLYGON ((370907.330099999904697 3418398.496099999174576, 370899.395100000314615 3418410.75789999861853, 370909.574500000104318 3418415.690899999812245))

3 代码实现

3.1 CGCS2000转WGS84

上面的这个字符串表示的是CGCS2000坐标系下的数据。下面的代码实现了将多边形地块坐标转换为WGS84,再从WGS84转换为BD09。

package cn.wja.utils;import cn.wja.model.BD09Point;
import cn.wja.model.PolygonResult;
import com.esri.arcgisruntime.geometry.*;import java.util.ArrayList;
import java.util.List;/*** 用于坐标转换的工具类** @author wang.jingan* @since 2019-07-20 10:39:16*/
public class CoordinateSystemTransform {/*** 通过String字符串得到三个坐标系的空间数据对象** @param  shape 转化为String的Geometry数据* @return  PolygonResult对象,内含三个坐标系的空间数据对象*/public  static PolygonResult shapeStringToPolygons(String shape) {//获取两个坐标系SpatialReference cgcs2000 = SpatialReference.create(4544);SpatialReference wgs84 = SpatialReference.create(4326);//创建一个CGCS2000的点收集器,为创建Polygon对象做准备PointCollection land = new PointCollection(cgcs2000);//准备返回的百度坐标点集合List<BD09Point> pointsBD09 = new ArrayList<>();//获取需要的字符串String shapeSubstring = shape.substring(10, shape.length() - 2);//得到每个点的原始数据String[] points = shapeSubstring.split(",");//遍历每个点for (String pointString : points) {//去前后的空格pointString = pointString.trim();//把经纬度分开成两个数据String[] xy = pointString.split(" ");Double x = Double.valueOf(xy[0]);Double y = Double.valueOf(xy[1]);//把点添加到点收集器land.add(x, y);//得到CGCS2000点数据Point pointCgcs2000 = new Point(x, y, cgcs2000);//把CGCS2000点数据转化为WGS84点数据Point pointwgs84 = (Point) GeometryEngine.project(pointCgcs2000, wgs84);//获取点数据中的经纬度,X为经度,Y为纬度double pointwgs84X = pointwgs84.getX();double pointwgs84Y = pointwgs84.getY();//把wgs84点坐标转化为bdo9点坐标double[] bd09 = GPSUtil.gps84_To_bd09(pointwgs84Y, pointwgs84X);BD09Point coordinatesDTO = new BD09Point();coordinatesDTO.setLat(bd09[0]);coordinatesDTO.setLon(bd09[1]);pointsBD09.add(coordinatesDTO);}//从点收集器中创建Polygon,得到一个cgcs2000的PolygonPolygon polygonCgcs2000 = new Polygon(land);//转换为wgs84的PolygonPolygon polygonWgs84 = (Polygon) GeometryEngine.project(polygonCgcs2000, wgs84);//装入返回数据PolygonResult result = new PolygonResult();result.setCgcs2000(polygonCgcs2000);result.setWgs84(polygonWgs84);result.setBd09(pointsBD09);return result;}
}

3.2 BD09坐标系中点的表示

在ArcGIS中wkid用于表示相关坐标系的代码, 并用SpatialReference.create(int wkid) 进行创建对应的坐标系。但BD09坐标系 在ArcGIS中没有相关的wkid,所以BD09坐标是通过点的集合表示,而WGS84的坐标是通过com.esri.arcgisruntime.geometry 包下的Polygon类的对象表示。
BD09坐标系的点是笔者自己定义的一个类。代码如下:

package cn.wja.model;public class BD09Point {private Double lat;private Double lon;public Double getLat() {return lat;}public void setLat(Double lat) {this.lat = lat;}public Double getLon() {return lon;}public void setLon(Double lon) {this.lon = lon;}@Overridepublic String toString() {return "BD09Point{" + "lat=" + lat + ", lon=" + lon + '}';}
}

3.3 WGS84转BD09

此工具类网上有很多,同时涉及到很多测量学和数学知识,我也不太擅长那些方面,所以就没有自己写,直接用了 高德,百度,Google地图定位偏移以及坐标系转换 这篇文章的代码,您也可以自行在网上寻找类似工具。

3.4测试结果

如下图所示,测试结果未发现异常。

4 依赖和环境

这篇文章首次发表是2019年7月,当时我用使用的ArcGIS Runtime SDK for Java版本为100.4.0。

<dependency><groupId>com.esri.arcgisruntime</groupId><artifactId>arcgis-java</artifactId><version>100.4.0</version>
</dependency>

当时是只需要在pom.xml中加入上面的依赖即可,默认配置的maven仓库或者阿里云仓库都可以自动下载jar包,也不需要安装任何ArcGIS环境,就可以使用运行。

但文章发布后大约半年,就陆续有开发者留言反馈说,不能正确加载jar包,报错提示“程序包com.esri.arcgisruntime.geometry不存在”。开始我以为是他们的Maven配置出了问题,我就手动下载100.8.0的jar文件,放在了我的CSDN资源中,供需要的朋友下载。之所以下载100.8.0版本,是因为原来的100.4.0的jar包我也没有刻意保存,也找不到了。但解决完jar包加载问题后,又有不少开发者反馈出现了如下报错:

Caused by: java.lang.RuntimeException: Could not find runtime in any of:
- A directory specified by calling ArcGISRuntimeEnvironment.setInstallDirectory()
- The current directory F:\Code\Intimate\other\gis-demo
- A location specified by the environment variable ARCGISRUNTIMESDKJAVA_100_10_0
- Within the “.arcgis” directory in the user’s home path C:\Users\admin.arcgis

我在自己的电脑上在测试,也重现了这个问题。开始我以为是100.8.0作为更高的版本,有其新的要求。我就花了不少功夫到arcgis的官网中找到并下载到了100.4.0的jar包,但是运行后也会报一样的错。我看这个jar包上传时间是2020年10月30日,估计是新下载的100.4.0,相对于2019年的文件,也做了些更新吧。

其实上述问题的实质就是ArcGIS Runtime API for Java的运行环境没有成功构建。

那么解决办法就只有两个了:

  • 第一个方法是找到老版本的100.4.0.jar。我尝试了很久,都没有找到相关资源,所以就暂时放弃了,如果有读者找到,可以联系我。
  • 第二个方法是使用新版本的jar包,并在此基础上构建ArcGIS Runtime API for Java的运行环境。我进行了一些探索后,成功实现了。
    解决办法请参见我新写的另一篇博客:《如何构建ArcGIS Runtime API for Java的运行环境》(左侧博客标题有超链接,请点击跳转)。
    您也可以直接下载示例代码:ArcGIS Runtime API for Java使用示例:CGCS2000转WGS84和BD09 (左侧资源标题含有超链接,请点击跳转 )。

5 提示

虽然我是通过公开途径下载的 ArcGIS Runtime API for Java 的相关jar包和资源文件,并未曾接收到任何关于收费的提示,但我也未查询到 ArcGIS Runtime API for Java 的供应商Esri 有表明这款软件是可以免费使用的开源软件。因此如需在实际项目开发中使用ArcGIS Runtime API for Java,请先向Esri公司咨询授权的相关事宜,避免不必要的纠纷和损失。
我在撰写本文时就职的公司是购买了ArcGIS 的软件使用权,在使用 ArcGIS Runtime API for Java时,也得到了Esri的技术支持。
如果您希望使用开源软件完成类似功能,建议查询一下geotools。

6 结语

本文的参考文献已经在正文中注明了出处。如果转载本文,也请注明出处和作者。这篇文章是我在CSDN上写的第一篇博客,时间仓促,技术有限,也不太了解CSDN上写博客的技巧,难免有些纰漏,欢迎读者指出其中的不足,也希望大家在博客下的留言区积极讨论。

如何把空间数据从CGCS2000转换到WGS84和BD09 ——JAVA语言实现相关推荐

  1. OFD文件转换成PDF格式,Java语言实现

    OFD文件转换成PDF格式,Java语言实现 我个人的思路大致是这样的.首先在指定路径创建一个文件夹,然后每次要转换的时候都把OFD文件统一放到指定的文件夹内进行转换.这样写代码的时候只需要循环遍历一 ...

  2. CGCS2000坐标系和WGS84坐标系的区别与联系

    01 概述 由于历史原因,业内普遍对WGS84坐标系存在一定程度的误解,诸多文献对WGS84坐标系的解释也比较含糊,给测绘.导航.遥感.地信等工作带来一定困扰.本文重点对CGCS2000坐标系与WGS ...

  3. PHP 不同地图坐标系经纬度转换 GCj02 WGS84 BD-09

    PHP 不同地图坐标系经纬度转换 GCj02 WGS84 BD-09 在项目中需要根据坐标计算距离,结果发现地图坐标不一致需要转换一下,在网上找到大佬写的一篇文章,亲测有效,原文地址: https:/ ...

  4. bd09转wgs84 java_各种坐标系互相转换(WGS84转换BD-09主要)

    背景:最近用百度地图加载几万个点,然后画多边形和线段,用百度API提供的方法一次转10个,超级慢,我就在后台调用转换方法,直接页面上去展示,结果7万个点画到地图用了几秒时间.分享一下,感觉有用点赞,还 ...

  5. Python3 Wgs84\gcj02\bd09\mercator\bd09mc坐标系转换与投影

    最基础的一组经纬度坐标转换,在网上找到过JavaScript和java版本的,但是没有找到python版本的,把JavaScript版本的改成了python版本的,能凑合用. "" ...

  6. 批量将postgis进行WGS84与bd-09,gcj-02坐标系转换

    WGS84与bd-09,gcj-02坐标系,百度经纬度与百度墨卡托之间互转 FreeGIS_Coordinate_Transform( in schema_name text, in table_na ...

  7. 使用JS将GPRMC转换成WGS84/GCJ02

    使用JS将GPRMC转换成WGS84/GCJ02 背景 Background 代码 Code GPRMC 转换成WGS84 WGS84转GCJ02 背景 Background 在物联网相关的 应用中, ...

  8. 各系地图坐标互相转换【JS版和Java版】

    各系地图坐标互相转换[JS版和Java版] 坐标说明 1.(地球坐标)美国GPS使用的是WGS84的坐标系统,以经纬度的形式来表示地球平面上的某一个位置. 2.(火星坐标)我国,出于国家安全考虑,国内 ...

  9. 编程笔试(解析及代码实现):国内各大银行(招商银行/浦发银行等)在线笔试常见题目(猴子吃桃/字符串逆序输出/一段话输出字的个数/单词大小转换等)及其代码实现(Java/Python/C#等)之详细攻略

    编程笔试(解析及代码实现):国内各大银行(招商银行/浦发银行等)在线笔试常见题目(猴子吃桃/字符串逆序输出/一段话输出字的个数/单词大小转换等)及其代码实现(Java/Python/C#等)之详细攻略 ...

  10. java 168转换成861_java实验-java语言面向对象编程基础

    java实验-java语言面向对象编程基础 (12页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 8.90 积分 广州大学学生实验报告广州大学学生实验报告 ...

最新文章

  1. (转)C语言字节对齐
  2. OKR简单通俗易懂的介绍,1分钟了解什么是OKR工作法
  3. (简单)华为荣耀4A SCL-TL00的usb调试模式在哪里打开的方法
  4. Kubernetes使用Jenkins服务器存储所有的kube.config文件
  5. observable_Java Observable setChanged()方法与示例
  6. 《KyLin学习理解》-01-KyLin麒麟的简介及其思想
  7. LeetCode(806)——写字符串需要的行数(JavaScript)
  8. azure不支持哪些语句 sql_新同事不讲武德,这SQL语句写得忒野了
  9. win10 安装低版本的 .net framework
  10. com scripting读书笔记
  11. .net core判断当前访问源是PC端还是移动端
  12. 联想g500网卡linux驱动,联想g500无线网卡驱动下载-lenovog500无线网卡驱动v10.0.0.225 官方版 - 极光下载站...
  13. Android中汉字转换为拼音
  14. 使用 Sublime开发 Jade
  15. java如何将字符串转化为日期_java如何将字符串转为日期
  16. wps忘保存关闭,数据恢复步骤
  17. IDOC的处理函数IDOC_INPUT_ORDERS的增强点的分析
  18. NetBIOS、WINS、DNS的联系和区别
  19. Python自制恶搞virus
  20. 超级计算机预测2月有雪寒潮,寒潮连续南下,冷冬毋庸置疑?权威专家:到明年二月底最终确定...

热门文章

  1. 如何使用《口袋操作系统 Ceedo 2.2.1.23 汉化破解版》
  2. 第一次跳槽总结(产品经理,简历面试)
  3. Java好还是网优好,java和seo哪个好
  4. 手机4g接台式计算机,我用4G手机开热点连接电脑网速很慢怎么回事
  5. 腾讯电脑管家卸载后的残留信息有哪些
  6. 怎么批量修改pdf文件名
  7. SlideLive:提供关系型PPT模板下载
  8. 华为服务器sn码查询网站,linux 查询服务器sn号
  9. Photoshop简单案例(5)——利用ps进行颜色替换
  10. python程序设计基础课后答案-Python语言程序设计基础(第2版)嵩天课后答案