Transformation 将形状文件从epsg:4326投影到epsg:32056时出错

Transformation 将形状文件从epsg:4326投影到epsg:32056时出错,transformation,geotools,Transformation,Geotools,我一直在尝试将Shapefile的投影从一个坐标系更改为另一个坐标系。我使用的shapefile将EPSG:4326作为其参考系统,我需要将其更改为EPSG:32056。 我使用Geotools API-20.0实现同样的目的 我已经尝试过geotools中可用的各种方法,比如使用重投影FeatureCollection、使用JTS、使用查询API将shapefile直接转换为其他坐标参考系 import java.awt.event.ActionEvent; import java

我一直在尝试将Shapefile的投影从一个坐标系更改为另一个坐标系。我使用的shapefile将EPSG:4326作为其参考系统,我需要将其更改为EPSG:32056。 我使用Geotools API-20.0实现同样的目的

我已经尝试过geotools中可用的各种方法,比如使用重投影FeatureCollection、使用JTS、使用查询API将shapefile直接转换为其他坐标参考系

   import java.awt.event.ActionEvent;
   import java.io.File;
   import java.io.InputStream;
   import java.io.Serializable;
   import java.net.URI;
   import java.net.URL;

    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;

    import javax.swing.Action;
    import javax.swing.JButton;
    import javax.swing.JOptionPane;
    import javax.swing.JToolBar;
    import javax.swing.SwingWorker;

    import org.geotools.data.DataStore;

import org.geotools.data.DataStoreFactorySpi;
import org.geotools.data.DefaultTransaction;
import org.geotools.data.FeatureWriter;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.Query;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.data.simple.SimpleFeatureStore;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.map.FeatureLayer;
import org.geotools.map.Layer;
import org.geotools.map.MapContent;
import org.geotools.referencing.CRS;
import org.geotools.referencing.ReferencingFactoryFinder;
import org.geotools.referencing.factory.gridshift.GridShiftLocator;
import org.geotools.styling.SLD;
import org.geotools.styling.Style;
import org.geotools.swing.JMapFrame;
import org.geotools.swing.JProgressWindow;
import org.geotools.swing.action.SafeAction;
import org.geotools.swing.data.JFileDataStoreChooser;
import org.locationtech.jts.geom.Envelope;
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureVisitor;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.FeatureType;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.util.ProgressListener;

import com.vividsolutions.jts.geom.Geometry;

public class CRSLab {

    private File sourceFile;
    private SimpleFeatureSource featureSource;
    private MapContent map;

    public static void main(String[] args) throws Exception {
        CRSLab lab = new CRSLab();
        lab.displayShapefile();
    }

    // docs end main
    /**
     * This method:
     * <ol type="1">
     * <li>Prompts the user for a shapefile to display
     * <li>Creates a JMapFrame with custom toolbar buttons
     * <li>Displays the shapefile
     * </ol>
     */
    // docs start display
    private void displayShapefile() throws Exception {
        sourceFile = JFileDataStoreChooser.showOpenFile("shp", null);
        if (sourceFile == null) {
            return;
        }
        FileDataStore store = FileDataStoreFinder.getDataStore(sourceFile);
        featureSource = store.getFeatureSource();

        // Create a map context and add our shapefile to it
        map = new MapContent();
        Style style = SLD.createSimpleStyle(featureSource.getSchema());
        Layer layer = new FeatureLayer(featureSource, style);
        map.layers().add(layer);

        // Create a JMapFrame with custom toolbar buttons
        JMapFrame mapFrame = new JMapFrame(map);
        mapFrame.enableToolBar(true);
        mapFrame.enableStatusBar(true);

        JToolBar toolbar = mapFrame.getToolBar();
        toolbar.addSeparator();
        toolbar.add(new JButton(new ValidateGeometryAction()));
        toolbar.add(new JButton(new ExportShapefileAction()));

        // Display the map frame. When it is closed the application will exit
        mapFrame.setSize(800, 600);
        mapFrame.setVisible(true);
    }
    // docs end display


    // docs start export
    private void exportToShapefile() throws Exception {
        SimpleFeatureType schema = featureSource.getSchema();
        JFileDataStoreChooser chooser = new JFileDataStoreChooser("shp");
        chooser.setDialogTitle("Save reprojected shapefile");
        chooser.setSaveFile(sourceFile);
        int returnVal = chooser.showSaveDialog(null);
        if (returnVal != JFileDataStoreChooser.APPROVE_OPTION) {
            return;
        }
        File file = chooser.getSelectedFile();
        if (file.equals(sourceFile)) {
            JOptionPane.showMessageDialog(null, "Cannot replace " + file);
            return;
        }

        // set up the math transform used to process the data
        CoordinateReferenceSystem dataCRS = schema.getCoordinateReferenceSystem();
        CoordinateReferenceSystem worldCRS = CRS.decode("EPSG:32056", true);// map.getCoordinateReferenceSystem();
        boolean lenient = true; // allow for some error due to different datums
        MathTransform transform = CRS.findMathTransform(dataCRS, worldCRS, lenient);

        // grab all features
        SimpleFeatureCollection featureCollection = featureSource.getFeatures();

        // And create a new Shapefile with a slight modified schema
        DataStoreFactorySpi factory = new ShapefileDataStoreFactory();
        Map<String, Serializable> create = new HashMap<String, Serializable>();
        create.put("url", file.toURI().toURL());
        create.put("create spatial index", Boolean.TRUE);
        DataStore dataStore = factory.createNewDataStore(create);
        SimpleFeatureType featureType = SimpleFeatureTypeBuilder.retype(schema, worldCRS);
        dataStore.createSchema(featureType);
        String createdName = dataStore.getTypeNames()[0];
        // carefully open an iterator and writer to process the results
        Transaction transaction = new DefaultTransaction("Reproject");
        FeatureWriter<SimpleFeatureType, SimpleFeature> writer = dataStore.getFeatureWriterAppend(createdName,
                transaction);
        SimpleFeatureIterator iterator = featureCollection.features();
        try {
            int counter = 0;
            while (iterator.hasNext()) {
                // copy the contents of each feature and transform the geometry
                SimpleFeature feature = iterator.next();
                SimpleFeature copy = writer.next();

                org.locationtech.jts.geom.Geometry geometry = (org.locationtech.jts.geom.Geometry) feature
                        .getDefaultGeometry();
                org.locationtech.jts.geom.Geometry geometry2 = JTS.transform(geometry, transform);
                System.out.println(geometry.isSimple() && geometry2.isSimple());
                // if (geometry2.isValid()) {
                copy.setAttributes(feature.getAttributes());
                counter++;
                copy.setDefaultGeometry(geometry2);
                writer.write();
                // }
            }
            transaction.commit();
            System.out.println("valid geometries : " + counter);
            JOptionPane.showMessageDialog(null, "Export to shapefile complete");
        } catch (Exception problem) {
            problem.printStackTrace();
            transaction.rollback();
            JOptionPane.showMessageDialog(null, "Export to shapefile failed");
        } finally {
            writer.close();
            iterator.close();
            transaction.close();
        }
    }
    // docs end export

        // docs start validate
    private int validateFeatureGeometry(ProgressListener progress) throws Exception {
        final SimpleFeatureCollection featureCollection = featureSource.getFeatures();

        // Rather than use an iterator, create a FeatureVisitor to check each
        // fature
        class ValidationVisitor implements FeatureVisitor {
            public int numInvalidGeometries = 0;

            public void visit(Feature f) {
                SimpleFeature feature = (SimpleFeature) f;
                Geometry geom = (Geometry) feature.getDefaultGeometry();
                if (geom != null && !geom.isValid()) {
                    numInvalidGeometries++;
                    System.out.println("Invalid Geoemtry: " + feature.getID());
                }
            }
        }

        ValidationVisitor visitor = new ValidationVisitor();

        // Pass visitor and the progress bar to feature collection
        featureCollection.accepts(visitor, progress);
        return visitor.numInvalidGeometries;
    }
    // docs end validate

        // docs start export action
    class ExportShapefileAction extends SafeAction {
        ExportShapefileAction() {
            super("Export...");
            putValue(Action.SHORT_DESCRIPTION, "Export using current crs");
        }

        public void action(ActionEvent e) throws Throwable {
            exportToShapefile();
        }
    }
    // docs end export action

    /**
     * This class performs the task of checking that the Geometry of each
     * feature is topologically valid and reports on the results. It also
     * supplies the name and tool tip.
     */
    // docs start validate action
    class ValidateGeometryAction extends SafeAction {
        ValidateGeometryAction() {
            super("Validate geometry");
            putValue(Action.SHORT_DESCRIPTION, "Check each geometry");
        }

        public void action(ActionEvent e) throws Throwable {
            int numInvalid = validateFeatureGeometry(null);
            String msg;
            if (numInvalid == 0) {
                msg = "All feature geometries are valid";
            } else {
                msg = "Invalid geometries: " + numInvalid;
            }
            JOptionPane.showMessageDialog(null, msg, "Geometry results", JOptionPane.INFORMATION_MESSAGE);
        }
    }
        // docs end validate action

    }
导入java.awt.event.ActionEvent;
导入java.io.File;
导入java.io.InputStream;
导入java.io.Serializable;
导入java.net.URI;
导入java.net.URL;
导入java.util.HashMap;
导入java.util.Map;
导入java.util.Set;
导入javax.swing.Action;
导入javax.swing.JButton;
导入javax.swing.JOptionPane;
导入javax.swing.JToolBar;
导入javax.swing.SwingWorker;
导入org.geotools.data.DataStore;
导入org.geotools.data.DataStoreFactorySpi;
导入org.geotools.data.DefaultTransaction;
导入org.geotools.data.FeatureWriter;
导入org.geotools.data.FileDataStore;
导入org.geotools.data.FileDataStoreFinder;
导入org.geotools.data.Query;
导入org.geotools.data.Transaction;
导入org.geotools.data.shapefile.ShapefileDataStoreFactory;
导入org.geotools.data.simple.SimpleFeatureCollection;
导入org.geotools.data.simple.SimpleFeatureIterator;
导入org.geotools.data.simple.SimpleFeatureSource;
导入org.geotools.data.simple.SimpleFeatureStore;
导入org.geotools.feature.simple.SimpleFeatureTypeBuilder;
导入org.geotools.geometry.jts.jts;
导入org.geotools.geometry.jts.ReferenceDevelope;
导入org.geotools.map.FeatureLayer;
导入org.geotools.map.Layer;
导入org.geotools.map.MapContent;
导入org.geotools.reference.CRS;
导入org.geotools.reference.referencengFactoryFinder;
导入org.geotools.referenting.factory.gridshift.GridShiftLocator;
导入org.geotools.style.SLD;
导入org.geotools.Style.Style;
导入org.geotools.swing.JMapFrame;
导入org.geotools.swing.JProgressWindow;
导入org.geotools.swing.action.SafeAction;
导入org.geotools.swing.data.jfiledatastoreselector;
导入org.locationtech.jts.geom.Envelope;
导入org.opengis.feature.feature;
导入org.opengis.feature.FeatureVisitor;
导入org.opengis.feature.simple.SimpleFeature;
导入org.opengis.feature.simple.SimpleFeatureType;
导入org.opengis.feature.type.FeatureType;
导入org.opengis.reference.crs.CoordinateReferenceSystem;
导入org.opengis.reference.operation.MathTransform;
导入org.opengis.util.ProgressListener;
导入com.lividsolutions.jts.geom.Geometry;
公共类实验室{
私有文件源文件;
私有SimpleFeatureSource功能源;
私有地图内容地图;
公共静态void main(字符串[]args)引发异常{
CRSLab lab=新的CRSLab();
lab.displayShapefile();
}
//末端总管
/**
*此方法:
* 
*
  • 提示用户显示形状文件 *
  • 使用自定义工具栏按钮创建JMapFrame *
  • 显示形状文件 * */ //文档开始显示 私有void displayShapefile()引发异常{ sourceFile=jfiledatastoreselector.showOpenFile(“shp”,null); if(sourceFile==null){ 返回; } FileDataStore store=FileDataStoreFinder.getDataStore(sourceFile); featureSource=store.getFeatureSource(); //创建一个映射上下文并将我们的shapefile添加到其中 map=新的MapContent(); Style Style=SLD.createSimpleStyle(featureSource.getSchema()); 图层=新的FeatureLayer(featureSource,style); map.layers().add(层); //使用自定义工具栏按钮创建JMapFrame JMapFrame mapFrame=新的JMapFrame(map); mapFrame.enableToolBar(true); mapFrame.enableStatusBar(真); JToolBar toolbar=mapFrame.getToolBar(); toolbar.addSeparator(); add(newjbutton(newvalidategeometryAction()); 添加(新的JButton(新的ExportShapefileAction()); //显示地图框。当它关闭时,应用程序将退出 mapFrame.setSize(800600); mapFrame.setVisible(true); } //文档结束显示 //文件开始导出 私有void exportToShapefile()引发异常{ SimpleFeatureType架构=featureSource.getSchema(); JFileDataStoreSchooser=新的JFileDataStoreSchooser(“shp”); setDialogTitle(“保存重新投影的形状文件”); 选择器.setSaveFile(源文件); int returnVal=chooser.showsavedilog(null); if(returnVal!=jfiledatastoreselector.APPROVE\u选项){ 返回; } File File=chooser.getSelectedFile(); if(file.equals(sourceFile)){ showMessageDialog(null,“无法替换”+文件); 返回; } //设置用于处理数据的数学变换 CoordinateReferenceSystem dataCRS=schema.getCoordinateReferenceSystem(); CoordinateReferenceSystem worldCRS=CRS.decode(“EPSG:32056”,true);//map.getCoordinateReferenceSystem(); boolean lenient=true;//允许由于不同基准而出现一些错误 MathTransform=CRS.findMathTransform(数据转换、世界转换、宽大); //抓取所有功能 SimpleFeatureCollection featureCollection=featureSource.getFeatures(); //并创建一个新的Shapefile,其中包含一个稍微修改过的模式 DataStoreFactorySpi工厂=新的ShapefileDataStoreFactory(); Map create=newhashmap(); create.put(“url”,file.toURI().tour()); create.put(“创建空间索引”,Boolean.TRUE); DataStore DataStore=factory.createNewDataStore(create); SimpleFeatureType featureType=SimpleFeatureTypeBuilder.retype(模式,worldCRS);