项目场景:
项目里遇到一个问题,需要将2000国家大地坐标系的界址点生成的Polygon转换成经纬度坐标系的Polygon。
从网上找到了wkt坐标系转换的方法:
生成几何图形:
public static Geometry createGeometry(String wkt,int srid){
if (StringUtils.isEmpty(wkt)){
return null;
}
try {
WKTReader reader = new WKTReader();
Geometry geometry = reader.read(wkt);
geometry.setSRID(srid);
return geometry;
} catch (Exception e){
e.printStackTrace();
}
return null;
}
坐标系转换:
public static Geometry coordinateTransform(Geometry sourceGeometry,int targetSrid){
if (sourceGeometry == null || sourceGeometry.getSRID() == 0 || targetSrid == 0){
return null;
}
try {
//固定轴顺序
CRSAuthorityFactory factory = CRS.getAuthorityFactory(true);
//源坐标系
CoordinateReferenceSystem source = factory.createCoordinateReferenceSystem("EPSG:" + sourceGeometry.getSRID());
//目标坐标系
CoordinateReferenceSystem target = factory.createCoordinateReferenceSystem("EPSG:" + targetSrid);
//建立转换
MathTransform transform = CRS.findMathTransform(source, target,true);
//转换
Geometry res = JTS.transform(sourceGeometry, transform);
if (res != null){
//设置srid
res.setSRID(targetSrid);
}
return res;
}catch (FactoryException | org.opengis.referencing.operation.TransformException e){
e.printStackTrace();
}
return null;
}
需要用到的类:
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.io.WKTWriter;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CRSAuthorityFactory;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
遇到的问题
在使用Gradle引用依赖的时候,遇到了一些问题。需要下载的依赖包一直下载不下来
dependencies {
implementation 'org.geotools:gt-shapefile:23-RC'
implementation 'org.geotools:gt-swing:23-RC'
implementation 'org.geotools:gt-epsg-hsql:23-RC'
}
解决过程:
需要指定工件仓库"https://repo.osgeo.org/repository/release/",但由于我项目中还有其他的依赖,因此还有别的仓库地址
repositories {
maven {
url "https://repo.osgeo.org/repository/release/"
}
maven {
url "https://maven.aliyun.com/repository/central"
}
}
然而正是这两个仓库,引发了别的问题:
Could not resolve all files for configuration':compileClasspath'.
> Could not find jai_core.jar (javax.media:jai_core:1.1.3).
说是找不到jai_core.jar这个依赖包,说起来也是奇怪,我上阿里的仓库里找了一下,明明就有,为啥找不到呢?
经过一系列的尝试,怀疑是geotools这堆依赖包里也依赖了jai_core.jar,于是想办法对指定依赖的仓库地址(参考gradle的官方说明书):
repositories {
maven {
url "https://repo.osgeo.org/repository/release/"
content {
// this repository *only* contains artifacts with group "org.geotools"
includeGroup "org.geotools"
}
}
maven {
url "https://maven.aliyun.com/repository/central"
}
}
但是项目使用的gradle版本过低,不能识别content关键词,因此不能使用这个方法,于是转而尝试另一种解决方案:
dependencies {
implementation ('org.geotools:gt-shapefile:23-RC'){
exclude group:'javax.media',module:'jai_core'
}
implementation ('org.geotools:gt-swing:23-RC'){
exclude group:'javax.media',module:'jai_core'
}
implementation ('org.geotools:gt-epsg-hsql:23-RC'){
exclude group:'javax.media',module:'jai_core'
}
}
至此问题解决,附上整体代码仅供参考:
/**
* @ClassName GeometryUtil
* @Description 图形工具
* @Author MOsilu
* @Date 2023/8/29 10:43
**/
public final class GeometryUtil {
public GeometryUtil() {
}
/**
* 坐标系转换方法
* @param sourceGeometry
* @param targetSrid
* @return
*/
public static Geometry coordinateTransform(Geometry sourceGeometry,int targetSrid){
if (sourceGeometry == null || sourceGeometry.getSRID() == 0 || targetSrid == 0){
return null;
}
try {
//固定轴顺序
CRSAuthorityFactory factory = CRS.getAuthorityFactory(true);
//源坐标系
CoordinateReferenceSystem source = factory.createCoordinateReferenceSystem("EPSG:" + sourceGeometry.getSRID());
//目标坐标系
CoordinateReferenceSystem target = factory.createCoordinateReferenceSystem("EPSG:" + targetSrid);
//建立转换
MathTransform transform = CRS.findMathTransform(source, target,true);
//转换
Geometry res = JTS.transform(sourceGeometry, transform);
if (res != null){
//设置srid
res.setSRID(targetSrid);
}
return res;
}catch (FactoryException | org.opengis.referencing.operation.TransformException e){
e.printStackTrace();
}
return null;
}
/**
* 生成几何图形
* @param wkt
* @param srid
* @return
*/
public static Geometry createGeometry(String wkt,int srid){
if (StringUtils.isEmpty(wkt)){
return null;
}
try {
WKTReader reader = new WKTReader();
Geometry geometry = reader.read(wkt);
geometry.setSRID(srid);
return geometry;
} catch (Exception e){
e.printStackTrace();
}
return null;
}
public static String writerGeometry(Geometry geometry) {
if (Objects.isNull(geometry)) {
return "";
}
WKTWriter writer = new WKTWriter();
return writer.write(geometry);
}
}
int srid = 0;
if (firstX > 35000000 && firstX <= 36000000) {
srid = 4523;
} else if (firstX > 36000000 && firstX <= 37000000) {
srid = 4524;
} else if (firstX > 37000000 && firstX <= 38000000) {
srid = 4525;
} else if (firstX > 38000000 && firstX <= 39000000) {
srid = 4526;
}
LinearRing r1 = new GeometryFactory().createLinearRing(lastRing.toArray(new Coordinate[lastRing.size()]));
subRing.add(r1);
val md = new PrecisionModel();
GeometryFactory fc = new GeometryFactory(md, srid);
Polygon polygon = fc.createPolygon(fc.createLinearRing(mainRing.toArray(new Coordinate[mainRing.size()])), subRing.toArray(new LinearRing[subRing.size()]));
// 坐标系转换
Geometry source = GeometryUtil.createGeometry(polygon.toString(),srid);
Geometry res = GeometryUtil.coordinateTransform(source, 4490);
String wkt = GeometryUtil.writerGeometry(res);