从Polygon对象的Java中更新几何图形

时间:2014-02-27 16:44:58

标签: java jdbc postgis

我正在尝试使用外部文件中的数据更新PostGIs几何列。某些多边形中的点数超过35k,并且ST_GeomFromText方法不起作用,因为文本字符串太长。我可以将这些点读入Polygon对象,我想做类似的事情:

PreparedStatement ps = conn.preparedStatment("update x set y = ? where z = ?");
ps.setBinary(1, polygon);
ps.setString(2, key);
ps.executeUpdate();

我无法找到有关如何做到这一点的任何示例。有人可以指点我看文件或举一个我可以遵循的例子吗?

由于

2 个答案:

答案 0 :(得分:8)

所以,我做了一些测试,并为了你的利益掀起了下面的例子。我也只是将它作为GIST on Github提供,随意克隆和探索。

首先,这是我在新数据库gis_data中创建的表的DDL,该数据库构建在template_postgis数据库模板上:

CREATE TABLE sample_table
(
  "key" character varying(20) NOT NULL,
  large_poly geometry NOT NULL,
  CONSTRAINT simple_pl PRIMARY KEY (key)
)

此表用于我的Java示例,如下所示。请务必使用您的凭据修改DriverManager.getConnection()行。

import java.sql.*;
import java.util.*;
import java.lang.*;
import org.postgis.*;

public class JavaGIS {

    public static void main(String[] args) {
        java.sql.Connection conn;
        try {
            Class.forName("org.postgresql.Driver");
            String url = "jdbc:postgresql://localhost:5432/gis_data";
            conn = DriverManager.getConnection(url, "postgres", "");

            ((org.postgresql.PGConnection)conn).addDataType("geometry",Class.forName("org.postgis.PGgeometry"));
            ((org.postgresql.PGConnection)conn).addDataType("box3d",Class.forName("org.postgis.PGbox3d"));

            Polygon geo = new Polygon(
                            new LinearRing[] {
                                new LinearRing(
                                    new Point[] {
                                        new Point(-1.0d, -1.0d,  0.5d),
                                        new Point( 1.0d, -1.0d,  0.0d),
                                        new Point( 1.0d,  1.0d, -0.5d),
                                        new Point(-1.0d,  1.0d,  0.0d),
                                        new Point(-1.0d, -1.0d,  0.5d)
                                    }
                                )
                            }
                        );
            PreparedStatement s = conn.prepareStatement("INSERT INTO sample_table (key_value, large_poly) VALUES (?, ?)");
            s.setString(1, "poly1");
            s.setObject(2, new PGgeometry(geo));

            int rows = s.executeUpdate();

            if (rows > 0) {
                System.out.println(" Successful insert! ");
            } else {
                System.out.println(" Failed insert!");
            }
            s.close();

            Statement qs = conn.createStatement();
            ResultSet r = qs.executeQuery("SELECT key_value, large_poly FROM sample_table");
            while( r.next() ) {
                /*
                * Retrieve the geometry as an object then cast it to the geometry type.
                * Print things out.
                */
                String key = r.getString(1);
                PGgeometry geom = (PGgeometry)r.getObject(2);

                if (geom.getGeoType() == Geometry.POLYGON) {
                    System.out.println("Found a polygon with key " + key);
                } else {
                    System.out.println("Found a PostGIS geometry object " + geom.getGeoType() + " having key " + key);
                }
            }
            qs.close();
            conn.close();
        }
        catch( Exception e ) {
            e.printStackTrace();
        }
    }
}

在编译和执行此示例时,请务必在类路径中包含recent Postgresql jdbc driver jarPostGIS jar file

这个例子很大程度上基于PostGIS example,它说明选择如此精美和简单。插入也很简单,因为PostGIS在扩展方面做了很多工作。

如果您已将数据存储在PostGIS Geometry对象中,请在我的示例中执行此操作并将其包装在PGgeometry对象中以插入数据库。这将让数据库驱动程序处理它的传输方式(可能是二进制数据)。一旦我真正关注instructions on how to construct Polygons,一切都很顺利。

免责声明:我只用简单的多边形试过这个,但原则是合理的。让我知道你正在处理的非常大的多边形是怎么回事!

答案 1 :(得分:1)

很棒的工作。

但是我需要指定SRID(4326),否则数据库会拒绝多边形。

任何提示?

使用字符串解决它。

String bbox ="SRID=4326;POLYGON(("+lu+","+lo+","+ro+","+ru+","+lu+"))";
pstmt.setObject(12,new PGgeometry(bbox));