Java Geotools多多边形到数据库并返回

Java Geotools多多边形到数据库并返回,java,mysql,jdbc,geotools,Java,Mysql,Jdbc,Geotools,我正在读一组数据,其中包含大量的多类型文字。我正在使用Geotools,我想将此列表存储在mysql数据库表中 我不知道如何以有效的方式存储形状,并能够重新创建多多边形对象 如果我得到多多边形的坐标,那么我会得到一个数组,其中包含该几何体所有顶点的值(如果几何体是复合的,则该数组包含组件的所有顶点,按照组件在几何体中出现的顺序),但我不知道如何用这些坐标重新创建一个新的多多边形 请在下面找到我得到的信息 private List<Shape> parseFile2ShapeList(

我正在读一组数据,其中包含大量的多类型文字。我正在使用Geotools,我想将此列表存储在mysql数据库表中

我不知道如何以有效的方式存储形状,并能够重新创建多多边形对象

如果我得到多多边形的坐标,那么我会得到一个数组,其中包含该几何体所有顶点的值(如果几何体是复合的,则该数组包含组件的所有顶点,按照组件在几何体中出现的顺序),但我不知道如何用这些坐标重新创建一个新的多多边形

请在下面找到我得到的信息

private List<Shape> parseFile2ShapeList(File file) {

    List<Shape> shapes = new ArrayList<Shape>();
    FileDataStore myData = null;
    SimpleFeatureIterator sfit = null;
    try {
        // Extract all features
        myData = FileDataStoreFinder.getDataStore( file );
        SimpleFeatureSource source = myData.getFeatureSource();
        SimpleFeatureCollection sfc = source.getFeatures();
        sfit = sfc.features();

        // Read the features and store in a list only the ones with Venue_ID
        while (sfit.hasNext()) {
            SimpleFeature feature = sfit.next();
            String id = (String) feature.getAttribute("ID");
            MultiPolygon mulPoly = (MultiPolygon) feature.getAttribute("the_geom");
            Shape shape = new Shape(id, mulPoly);
            shapes.add(shape);
        }  
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        sfit.close();
        myData.dispose();
    }
    return shapes;
}

private boolean insertShapes(List<Shape> shapes) {
    // Insert the shapes in the DB
    boolean inserted = false;
    try (Database db = new Database()) {
        // Store in the DB all the shapes
        for (Shape shape : shapes) {
            db.getShapesDao().insertShape(shape); // What shall I store in the DB if the shape is a multipolygon? What if it is any Geometry?
        }   
        inserted = true;
    } catch (SQLException e) {
        e.printStackTrace();
        inserted = false;
    } catch (IOException e) {
        e.printStackTrace();
        inserted = false;
    }
    return inserted;
}

private Shape selectShape(String shape_id) {
    Shape shape = null;
    try (Database db = new Database()) {
        // Retrieve the shape
        shape = db.getShapesDao().getShapeById(shape_id); // How do I recreate a multipolygon (or any other Geometry inserted in the DB?)
    } catch (SQLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return shape;
}

public void main() {

    // display a data store file chooser dialog for shapefiles
    File file = JFileDataStoreChooser.showOpenFile("shp", null);
    if (file == null) {
        return;
    }

    // Read the file and load in memory the venues
    List<Shape> shapes = parseFile2ShapeList(file);
    System.out.println("Shapes parsed: " + retrieved.size());
    for (Shape shape : shapes) {
        System.out.println("\t ID: " + shape.getId() ); 
    }

    // Insert in database
    boolean inserted = insertVenues(venues);
    System.out.println("Insertion successful? " + inserted);

    // Retrieve from database
    List<Shape> retrievedShapes = new ArrayList<Shape>();
    for (Shape shape : shapes) {
        Shape retrieved = selectShape(shape.getId());
        retrievedShapes.add(retrieved);
    }
    System.out.println("Shapes retrieved: " + retrieved.size());
    for (Shape shape : retrievedShapes) {
        System.out.println("\t ID: " + shape.getId() ); 
    }
}
此表还有其他列,但目前它们并不相关。在任何情况下,给定输入文件,我希望将每个几何体(
shape
column)存储在不同的行中

在我的程序中,给定一个
shape\u id
,我想检索有关该形状的相关信息(
shape
列),然后构造几何体。

(未测试)Geotools有一个MySQL数据存储:

也记录在这里:

您应该能够获取从SHP读取的FeatureCollection并将其推送到新的数据存储。因此,

SimpleFeatureCollection sfc 
是要传递给为此数据存储定义的SimpleFeatureSource源的内容。差不多

DataUtilities.source( collection );
根据用户指南:


希望这能有所帮助。

你的工作水平太低,因此给自己造成了困难。GeoTools的设计(适用于大多数用户/使用)是为了与数据存储一起工作,这些数据存储将细节提取出来,并为您处理几何图形和属性。因此,您的问题分为两部分:第一部分读取shapefile,第二部分将特性写入数据库。您已经成功地完成了第一步,第二步有点棘手,但相当简单

获取到数据库的连接(我在安装PostGIS时使用了它,但MySql应该以同样的方式工作):

然后将功能发送到数据源:

SimpleFeatureSource featureSource = dataStore
.getFeatureSource(schema.getName().getLocalPart());
if (featureSource instanceof SimpleFeatureStore) {
    SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
    featureStore.setTransaction(transaction);
    try {
        List < FeatureId > ids = featureStore.addFeatures(features);
        transaction.commit();
    } catch (Exception problem) {
        problem.printStackTrace();
        transaction.rollback();
    } finally {
        transaction.close();
    }
    dataStore.dispose();
    return true;
} else {
    dataStore.dispose();
    System.err.println("Database not writable");
    return false;
}
SimpleFeatureSource featureSource=数据存储
.getFeatureSource(schema.getName().getLocalPart());
if(SimpleFeatureStore的功能源实例){
SimpleFeatureStore featureStore=(SimpleFeatureStore)featureSource;
featureStore.setTransaction(事务);
试一试{
Listids=featureStore.addFeatures(features);
commit();
}捕获(异常问题){
问题:printStackTrace();
transaction.rollback();
}最后{
transaction.close();
}
dataStore.dispose();
返回true;
}否则{
dataStore.dispose();
System.err.println(“数据库不可写”);
返回false;
}

如果需要的话,新表的句柄创建会有点混乱,就像您在中看到的那样,它会在需要时创建一个新表或附加到现有表

我找到的解决方案是使用WKTWriter和wktrader类。这是我在DAO课上写的:

static private String INSERT_SHAPE = "INSERT INTO shape_table(shape_id, shape) VALUES (?, ?)";

static private String GET_SHAPE_BY_ID = "SELECT shape FROM shape_table WHERE shape_id = ?";


public void insertShape(String shape_id, Geometry shape) throws SQLException {
    try (PreparedStatement s = connection.prepareStatement(INSERT_SHAPE)) {
        s.setString(1, shape_id);
        WKTWriter writer = new WKTWriter();
        String wkt = writer.write(shape);
        s.setString(2, wkt);
        s.executeUpdate();
    }
}

public Geometry getShapeById(String shape_id) throws SQLException, ParseException {
    String wkt = null;
    Geometry shape = null;
    WKTReader reader = new WKTReader();
    try (PreparedStatement s = connection.prepareStatement(GET_SHAPE_BY_ID)) {
        s.setString(1, shape_id);
        ResultSet rs = s.executeQuery();
        if (rs.next()) {
            wkt = rs.getString("shape");
            shape = reader.read(wkt);
        }
        return shape;
    }
}

这个解决方案让我很满意,因为在DB表中,我可以看到整个几何图形,并将其余信息存储在已经以特定方式创建的表中。当然我很想听听你的意见。

谢谢!我正在调查,但似乎找不到我需要的东西。数据存储似乎更多地用于检索信息,而不是在给定的mysql表中插入信息。我将编辑问题,添加更多细节。谢谢伊恩!我不喜欢在数据存储中进行参数配置的方式,如果我只想保存功能的某些特定属性,我不确定代码是否更容易阅读(我可能必须过滤掉我不想存储的属性)。我刚刚发布了一个替代解决方案,但我很高兴听到您的想法。如果您愿意以这种方式处理连接,可以使用JNDI。选择某些属性的最简单方法是将查询传递到shapefile数据存储,该数据存储限制了返回的属性,并允许您过滤返回的功能。Iant的答案是正确的。有关更多培训(使用shp数据存储)的信息,请参见此处操作要存储在要素中的属性,您可以操作模式(请参见提供的链接了解如何创建模式)。如果要创建子集,请查看以下内容:DataUtilities.createSubType(SimpleFeatureType,String[]),在这里,这将减慢读/写速度,并防止数据库索引几何体。它还将阻止您在db上使用标准映射工具。此解决方案基本上不使用Geotools。它与几何体的JTS一起工作。这是一个非常低级的解决方案,会在依赖其他高级地理工具的生产实现中造成问题。也不操纵整个要素,只操纵几何图形(未类型化)。你可能会最终混合线、点和多边形等。。。取决于后端,这可能是也可能是不可能的。正如上面的评论所说,此解决方案可能没有使用Geotools的潜力,并且可能是“低级”的,因为它在插入之前读取每个功能的特定属性(即_geom)。尽管如此,我还是用一个包含3000多个多边形和多多边形的文件测试了这个解决方案,我在shape文件中的内容始终与插入后从mysql表中检索到的内容相匹配。但是,请注意,我必须将表列类型从text更改为mediumtext。
SimpleFeatureSource featureSource = dataStore
.getFeatureSource(schema.getName().getLocalPart());
if (featureSource instanceof SimpleFeatureStore) {
    SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
    featureStore.setTransaction(transaction);
    try {
        List < FeatureId > ids = featureStore.addFeatures(features);
        transaction.commit();
    } catch (Exception problem) {
        problem.printStackTrace();
        transaction.rollback();
    } finally {
        transaction.close();
    }
    dataStore.dispose();
    return true;
} else {
    dataStore.dispose();
    System.err.println("Database not writable");
    return false;
}
static private String INSERT_SHAPE = "INSERT INTO shape_table(shape_id, shape) VALUES (?, ?)";

static private String GET_SHAPE_BY_ID = "SELECT shape FROM shape_table WHERE shape_id = ?";


public void insertShape(String shape_id, Geometry shape) throws SQLException {
    try (PreparedStatement s = connection.prepareStatement(INSERT_SHAPE)) {
        s.setString(1, shape_id);
        WKTWriter writer = new WKTWriter();
        String wkt = writer.write(shape);
        s.setString(2, wkt);
        s.executeUpdate();
    }
}

public Geometry getShapeById(String shape_id) throws SQLException, ParseException {
    String wkt = null;
    Geometry shape = null;
    WKTReader reader = new WKTReader();
    try (PreparedStatement s = connection.prepareStatement(GET_SHAPE_BY_ID)) {
        s.setString(1, shape_id);
        ResultSet rs = s.executeQuery();
        if (rs.next()) {
            wkt = rs.getString("shape");
            shape = reader.read(wkt);
        }
        return shape;
    }
}