0
点赞
收藏
分享

微信扫一扫

基于Java和GeoTools的shp文件坐标系转换


之前一直在使用GDAL进行shp文件的坐标系转换,但是最近遇到一个问题,GDAL的windows环境部署比较麻烦。我调试好的代码,交给别人后会出现无法运行的状况。于是研究了一下基于GeoTools的shp文件坐标系转换。最后发现,还是这种方式,操作起来,相对比较简单,对电脑环境依赖不高。

依赖

<?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>org.example</groupId>
    <artifactId>readShp</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <geo.version>9.3</geo.version>
    </properties>
    <dependencies>
        <!--        shp入库依赖-->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-shapefile</artifactId>
            <version>${geo.version}</version>
        </dependency>
        <dependency>
            <groupId>com.vividsolutions</groupId>
            <artifactId>jts</artifactId>
            <version>1.13</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-api</artifactId>
            <version>${geo.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-epsg-hsql</artifactId>
            <version>${geo.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-opengis</artifactId>
            <version>${geo.version}</version>
        </dependency>
    </dependencies>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>

        <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>
        <repository>
            <id>osgeo-snapshot</id>
            <name>OSGeo Snapshot Repository</name>
            <url>https://repo.osgeo.org/repository/snapshot/</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>


    </repositories>
</project>

Java代码

package com.test.shp;

import com.vividsolutions.jts.geom.Geometry;
import org.geotools.data.FeatureWriter;
import org.geotools.data.FileDataStoreFactorySpi;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;

import java.io.File;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;


public class ProjectTrans {

    public static void projectShape(String inputShp, String outputShp, Integer targetSrid) throws Exception {

        //源shape文件
        ShapefileDataStore shapeDS = (ShapefileDataStore) new ShapefileDataStoreFactory().createDataStore(new File(inputShp).toURI().toURL());
        //创建目标shape文件对象
        Map<String, Serializable> params = new HashMap<String, Serializable>();
        FileDataStoreFactorySpi factory = new ShapefileDataStoreFactory();
        params.put(ShapefileDataStoreFactory.URLP.key, new File(outputShp).toURI().toURL());
        ShapefileDataStore ds = (ShapefileDataStore) factory.createNewDataStore(params);
        CoordinateReferenceSystem crs = CRS.decode("EPSG:" + targetSrid);
        CoordinateReferenceSystem crsOld = shapeDS.getSchema().getCoordinateReferenceSystem();

        System.out.println(crsOld.getName());
        // 设置属性
        SimpleFeatureSource fs = shapeDS.getFeatureSource(shapeDS.getTypeNames()[0]);
        //下面这行还有其他写法,根据源shape文件的simpleFeatureType可以不用retype,而直接用fs.getSchema设置
        System.out.println(crs.getName());

        ds.createSchema(SimpleFeatureTypeBuilder.retype(fs.getSchema(), crs));
        ds.forceSchemaCRS(crs);

        //设置writer
        FeatureWriter<SimpleFeatureType, SimpleFeature> writer = ds.getFeatureWriter(ds.getTypeNames()[0], Transaction.AUTO_COMMIT);

        //写记录
        SimpleFeatureIterator it = fs.getFeatures().features();
        MathTransform transform = CRS.findMathTransform(crsOld, crs, true);
        //遍历要素
        try {
            while (it.hasNext()) {
                SimpleFeature f = it.next();
                SimpleFeature fNew = writer.next();
                fNew.setAttributes(f.getAttributes());

                //图形坐标变换
                Geometry geom = (Geometry) JTS.transform((Geometry) f.getAttribute("the_geom"), transform);
                fNew.setAttribute("the_geom", geom);

            }
        } finally {
            it.close();
        }
        writer.write();
        writer.close();
        ds.dispose();
        shapeDS.dispose();

    }

    public static void main(String[] args) throws Exception {
      projectShape("E:\\测试数据\\out.shp","E:\\测试数据\\result.shp",3857);
    }
}

运行中问题

在转换shp的过程中,部分shp文件出现了一个问题。如下图:

  • 转换前
  • 基于Java和GeoTools的shp文件坐标系转换_gis

  • 转换后
  • 基于Java和GeoTools的shp文件坐标系转换_GeoTools_02

从上面的图中,可以看出,发生了很大的变化,图形几乎是翻转了。这个问题困扰了我很久,最后终于找到了解决方案。这个是由于部分shp数据的xy的顺序反过来了导致的。在运行GeoTool是的代码初始位置加上下面的一句代码就可以解决:

System.setProperty("org.geotools.referencing.forceXY", "true");

在程序的初始位置加入上面代码后,转换结果正常。在ArcGIS验证,前后位置一致。


举报

相关推荐

0 条评论