geotools 转换 shpfile 坐标系

文章讲述了在Java项目中使用Geotools库处理Shapefile,遇到国外坐标系转换问题,国内坐标系转换正常。作者分享了Maven依赖列表,并提供了样例代码,寻求关于坐标系转换问题的解决方案。
摘要由CSDN通过智能技术生成

简要说明

在java利用geotools工具,将shpfile的坐标系转为指定坐标系。目前测试发现,国外坐标系转换有问题,转换处理的shpfile再去geoserver发布时,经纬度调转了,例如坐标系4547转3857;不过转国内坐标系4326/4490时,却正常。暂时还未定位到哪里问题,也欢迎留言指导一下。

maven依赖

<dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-shapefile</artifactId>
            <version>27.0</version>
        </dependency>
        <dependency>
            <groupId>org.geotools.jdbc</groupId>
            <artifactId>gt-jdbc-postgis</artifactId>
            <version>27.0</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-referencing</artifactId>
            <version>27.0</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-render</artifactId>
            <version>27.0</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-coverage</artifactId>
            <version>27.0</version>
        </dependency>
        <dependency>
            <groupId>it.geosolutions.imageio-ext</groupId>
            <artifactId>imageio-ext-utilities</artifactId>
            <version>1.4.4</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.conversantmedia/disruptor -->
        <dependency>
            <groupId>com.conversantmedia</groupId>
            <artifactId>disruptor</artifactId>
            <version>1.2.15</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.geotools/gt-geojson -->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geojson</artifactId>
            <version>27.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.geotools/gt-epsg-hsql -->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-epsg-hsql</artifactId>
            <version>27.0</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-main</artifactId>
            <version>27.0</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-opengis</artifactId>
            <version>27.0</version>
        </dependency>
        <dependency>
            <groupId>si.uom</groupId>
            <artifactId>si-quantity</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>si.uom</groupId>
            <artifactId>si-units</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>tech.uom.lib</groupId>
            <artifactId>uom-lib-common</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>systems.uom</groupId>
            <artifactId>systems-common</artifactId>
            <version>2.0.2</version>
        </dependency>

样例代码

/**
*dataPath 源数据路径
*srid 指定的坐标系
* outputPath 输出的路径
**/
public void changeShpSrid(String dataPath, Integer srid, String outputPath) {
        ShapefileDataStore inputDataStore = null;
        ShapefileDataStore outputDataStore = null;
        try {
            File inputFile = new File(dataPath);
            //判断文件是否存在
            if(!inputFile.exists()) {
            	System.out.println("源文件不存在");
            	return;
            }
            Map<String, Serializable> inputParams = new HashMap<>();
            inputParams.put("url", inputFile.toURI().toURL());
            inputDataStore = (ShapefileDataStore)DataStoreFinder.getDataStore(inputParams);
            //一般shpfile的编码都是gbk
            inputDataStore.setCharset(Charset.forName("GBK"));

            // 获取输入Shapefile的FeatureSource和Schema
            String typeName = inputDataStore.getTypeNames()[0];
            SimpleFeatureType schema = inputDataStore.getSchema(typeName);

            // 创建输出Shapefile
            File outputFile = new File(outputPath);
            ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
            Map<String, Serializable> outputParams = new HashMap<>();
            outputParams.put("url", outputFile.toURI().toURL());
            outputParams.put("create spatial index", Boolean.TRUE);
            outputDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(outputParams);
            outputDataStore.createSchema(schema);
            outputDataStore.setCharset(Charset.forName("GBK"));

            // 设置目标坐标系
            CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:" + srid);
            outputDataStore.forceSchemaCRS(targetCRS);

            // 获取FeatureWriter来写入输出Shapefile
            String outputTypeName = outputDataStore.getTypeNames()[0];
            FeatureWriter<SimpleFeatureType, SimpleFeature> writer = outputDataStore.getFeatureWriterAppend(outputTypeName, Transaction.AUTO_COMMIT);

            CRSAuthorityFactory factory = CRS.getAuthorityFactory(true);
            SimpleFeatureIterator featureIterator = inputDataStore.getFeatureSource(typeName).getFeatures().features();

            Feature firstFeature = featureIterator.next();
            //拿到第一 feature的目的是为了拿到源文件的坐标系
            //第一条数据转坐标系
            Geometry firstGeometry = (Geometry) ((SimpleFeature) firstFeature).getDefaultGeometry();
            SimpleFeatureType sourceSimpleFeatureType = inputDataStore.getSchema();
            CoordinateReferenceSystem coordinateReferenceSystem = sourceSimpleFeatureType.getCoordinateReferenceSystem();
            changeNewSrid(factory, coordinateReferenceSystem, (SimpleFeature)firstFeature, firstGeometry, srid);


            // 读取输入Shapefile中的每个Feature,转换坐标系,并写入输出Shapefile
            while (featureIterator.hasNext()) {
                SimpleFeature feature = featureIterator.next();
                Geometry sourceGeometry = (Geometry) feature.getDefaultGeometry();
                SimpleFeature fNew = writer.next();
                fNew.setAttributes(feature.getAttributes());

                changeNewSrid(factory, coordinateReferenceSystem, fNew, sourceGeometry, srid);
            }

            featureIterator.close();
            // 关闭writer和datastore
            writer.close();
        } catch (IOException e) {
            System.out.println("文件流异常")
        } catch (FactoryException e) {
            System.out.println("获取geotools处理工厂异常");
        } finally {
            inputDataStore.dispose();
            outputDataStore.dispose();
        }
    }

private void changeNewSrid(CRSAuthorityFactory factory, CoordinateReferenceSystem fileSrid, SimpleFeature feature
            , Geometry sourceGeometry , Integer targetSrid) {
        CoordinateReferenceSystem targetCoordinate = null;
        try {
            //目标坐标系
            targetCoordinate = factory.createCoordinateReferenceSystem("EPSG:" + targetSrid);
            //建立转换
            MathTransform transform = CRS.findMathTransform(fileSrid, targetCoordinate, true);
            //转换
            Geometry res = JTS.transform(sourceGeometry, transform);
            feature.setDefaultGeometry(res);
        } catch (FactoryException e) {
            System.out.println("获取转换工厂异常");
        } catch (TransformException e) {
            System.out.println("shpfile转换坐标系失败");
        }
    }
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
非常抱歉,我之前的回答有误。Geotools确实不支持直接的投影转换到EPSG:4479坐标系。 EPSG:4479代表了ETRS89地理坐标系,它使用欧洲地面参考系统1989(ETRS89)作为基准。在Geotools中,大多数投影转换都是基于投影坐标系,而不是地理坐标系。 如果你希望进行与EPSG:4479相关的操作,可能需要考虑以下两种方式: 1. 将你的数据从投影坐标系转换到EPSG:4326(WGS84)地理坐标系,然后再进行与EPSG:4479的转换。这可以通过使用Geotools中的投影转换工具来实现。 2. 考虑使用其他的GIS库或工具,如GDAL(Geospatial Data Abstraction Library),它提供了更广泛的坐标系支持,包括对EPSG:4479的转换。 请注意,无论你选择哪种方式,确保你有正确的Bursa-Wolf参数(七参数或三参数)用于进行转换。这些参数通常用于处理不同基准之间的差异。 对于EPSG:4479,下面是一个示例使用Geotools进行从投影坐标系(如EPSG:3857)到EPSG:4479地理坐标系转换代码: ```java CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:3857"); CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4479"); MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true); DirectPosition2D sourcePos = new DirectPosition2D(sourceCRS, x, y); DirectPosition2D targetPos = new DirectPosition2D(); transform.transform(sourcePos, targetPos); double targetX = targetPos.getX(); double targetY = targetPos.getY(); ``` 请注意,以上示例中的转换是从EPSG:3857投影坐标系到EPSG:4479地理坐标系。确保你根据实际情况调整源和目标坐标系的EPSG代码。 希望这可以帮助到你。再次对之前的回答错误表示抱歉。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值