java geotools支持不同的坐标系之间进行转换,只需要转换的时候指定坐标系即可。
pom依赖文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cr.cdrb</groupId>
<artifactId>geo1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<geotools.version>20.0</geotools.version>
</properties>
<repositories>
<!-- <repository>
<id>boundless</id>
<name>boundless</name>
<url>https://repo.boundlessgeo.com/main/</url>
</repository>-->
<!--指定org.geotools的仓库地址-->
<repository>
<id>osgeo</id>
<name>OSGeo Release Repository</name>
<url>https://repo.osgeo.org/repository/release/</url>
<snapshots><enabled>false</enabled></snapshots>
<releases><enabled>true</enabled></releases>
</repository>
</repositories>
<dependencies>
<!--指定org.geotools jar包依赖-->
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-api</artifactId>
<version>${geotools.version}</version>
<exclusions>
<exclusion>
<groupId>javax.media</groupId>
<artifactId>jai_core</artifactId>
</exclusion>
<exclusion>
<groupId>jgridshift</groupId>
<artifactId>jgridshift</artifactId>
</exclusion>
<exclusion>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
</exclusion>
<exclusion>
<groupId>net.sf.geographiclib</groupId>
<artifactId>GeographicLib-Java</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--指定坐标系查询数据库 代码中指定的坐标系会从这里查询,只支持其中有的坐标系-->
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-hsql</artifactId>
<version>${geotools.version}</version>
</dependency>
</dependencies>
</project>
如果依赖下不下来,也可以去仓库自行下载,地址:Nexus Repository Manager
JAVA代码:
package geo1;
import org.locationtech.jts.geom.Coordinate;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import java.math.BigDecimal;
import java.text.DecimalFormat;
public class MyGeotools {
public static void main(String[] args) {
//某点的度分秒格式的经纬度,如果经纬度本身就是double格式的,就不需要再行计算
Double y = Double.parseDouble(getPosition("32°11′38.977458″"));//纬度
Double x = Double.parseDouble(getPosition("119°31′06.853758″"));//经度
Double[] coordinate = getCoordinate(x, y);
System.out.println("Y:"+coordinate[0] + " " + "X:"+coordinate[1]);
}
//坐标转换
public static Double[] getCoordinate(Double x, Double y) {
Double[] res = new Double[2];
Coordinate tar = null;
try {
//封装点,这个是通用的,也可以用POINT(y,x)
// private static WKTReader reader = new WKTReader( geometryFactory );
Coordinate sour = new Coordinate(y, x);
//这里要选择转换的坐标系是可以随意更换的
CoordinateReferenceSystem source = CRS.decode("EPSG:4326");
CoordinateReferenceSystem target = CRS.decode("EPSG:4549");
//建立转换,下面两个我屏掉的转换方式会报出需要3/7参数的异常
// MathTransform mathTransform = CRS.findMathTransform(source, target);
//MathTransform mathTransform1 = CRS.findMathTransform(source, target, false);
MathTransform transform = CRS.findMathTransform(source, target, true);
tar = new Coordinate();
//转换
JTS.transform(sour, tar, transform);
} catch (FactoryException | org.opengis.referencing.operation.TransformException e) {
e.printStackTrace();
}
String[] split = (tar.toString().substring(1, tar.toString().length() - 1)).split(",");
//经纬度精度
DecimalFormat fm = new DecimalFormat("0.0000000");
res[0] = Double.valueOf(fm.format(Double.valueOf(split[0])));
res[1] = Double.valueOf(fm.format(Double.valueOf(split[1])));
return res;
}
private static String getPosition(String position){
String[] degree = position.split("\\°");
if(degree.length == 1){
return position;
}
String d = degree[0];
String[] one = degree[1].split("\\′");
String a = one[0];
if(!a.contains(".")){
if(a.substring(0,1).equals("0")){
a = a.substring(1);
}
}else if(a.contains(".") && a.split("\\.").length > 1){
a = a.substring(1);
}
String[] two = one[1].split("\\″");
String b= two[0];
if(!b.contains(".")){
if(b.substring(0,1).equals("0")){
b = b.substring(1);
}
}else if(b.contains(".") && b.split("\\.").length > 1){
if(b.substring(0,1).equals("0")){
b = b.substring(1);
}
}
BigDecimal fen = new BigDecimal(a);
BigDecimal miao = new BigDecimal(b);
BigDecimal du = new BigDecimal(d);
// float f = Float.valueOf(a)+ Float.valueOf(Float.valueOf(b)/60);
// float du = Float.valueOf(f/60)+Float.valueOf(d);
BigDecimal add = fen.add(miao.divide(new BigDecimal("60"),6, BigDecimal.ROUND_HALF_UP)).divide(new BigDecimal("60"),6, BigDecimal.ROUND_HALF_UP).add(du);
return String.valueOf(add);
}
}
结果如图:
![](https://img-blog.csdnimg.cn/0b5190d1359d4c5baf9919ca44e243d7.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6YKj5Lqb5LmQ6Laj,size_20,color_FFFFFF,t_70,g_se,x_16)
注意,如果运行的时候报错如下:
No code "EPSG:4326" from authority "EPSG" found for object of type "EngineeringCRS".
那就是查找坐标系的数据库依赖没有引入,引入就可以了:
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-hsql</artifactId>
<version>${geotools.version}</version>
</dependency>
参考文档:
java geotools 坐标转换_不知工匠的博客-CSDN博客
No code "EPSG:4490" from authority "EPSG" found for object of type "EngineeringCRS".解决方案_徐先森的博客-CSDN博客