You can subscribe to this list here.
| 2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(39) |
Dec
(70) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2002 |
Jan
(52) |
Feb
(168) |
Mar
(248) |
Apr
(143) |
May
(418) |
Jun
(558) |
Jul
(702) |
Aug
(311) |
Sep
(141) |
Oct
(350) |
Nov
(172) |
Dec
(182) |
| 2003 |
Jan
(320) |
Feb
(362) |
Mar
(356) |
Apr
(218) |
May
(447) |
Jun
(203) |
Jul
(745) |
Aug
(494) |
Sep
(175) |
Oct
(422) |
Nov
(554) |
Dec
(162) |
| 2004 |
Jan
(217) |
Feb
(353) |
Mar
(228) |
Apr
(407) |
May
(211) |
Jun
(270) |
Jul
(264) |
Aug
(198) |
Sep
(268) |
Oct
(227) |
Nov
(118) |
Dec
(47) |
| 2005 |
Jan
(207) |
Feb
(243) |
Mar
(297) |
Apr
(197) |
May
(281) |
Jun
(166) |
Jul
(164) |
Aug
(92) |
Sep
(155) |
Oct
(196) |
Nov
(189) |
Dec
(114) |
| 2006 |
Jan
(129) |
Feb
(219) |
Mar
(274) |
Apr
(213) |
May
(245) |
Jun
(220) |
Jul
(376) |
Aug
(347) |
Sep
(179) |
Oct
(493) |
Nov
(448) |
Dec
(339) |
| 2007 |
Jan
(304) |
Feb
(273) |
Mar
(237) |
Apr
(186) |
May
(215) |
Jun
(320) |
Jul
(229) |
Aug
(313) |
Sep
(331) |
Oct
(279) |
Nov
(347) |
Dec
(266) |
| 2008 |
Jan
(332) |
Feb
(280) |
Mar
(203) |
Apr
(277) |
May
(301) |
Jun
(356) |
Jul
(292) |
Aug
(203) |
Sep
(277) |
Oct
(142) |
Nov
(210) |
Dec
(239) |
| 2009 |
Jan
(250) |
Feb
(193) |
Mar
(174) |
Apr
(183) |
May
(342) |
Jun
(230) |
Jul
(292) |
Aug
(161) |
Sep
(204) |
Oct
(280) |
Nov
(281) |
Dec
(175) |
| 2010 |
Jan
(113) |
Feb
(106) |
Mar
(199) |
Apr
(166) |
May
(298) |
Jun
(147) |
Jul
(175) |
Aug
(192) |
Sep
(71) |
Oct
(79) |
Nov
(58) |
Dec
(55) |
| 2011 |
Jan
(83) |
Feb
(169) |
Mar
(142) |
Apr
(207) |
May
(311) |
Jun
(183) |
Jul
(218) |
Aug
(190) |
Sep
(158) |
Oct
(197) |
Nov
(93) |
Dec
(74) |
| 2012 |
Jan
(92) |
Feb
(50) |
Mar
(64) |
Apr
(45) |
May
(100) |
Jun
(70) |
Jul
(3) |
Aug
(1) |
Sep
(2) |
Oct
(5) |
Nov
(7) |
Dec
(4) |
| 2013 |
Jan
(6) |
Feb
(2) |
Mar
(2) |
Apr
(4) |
May
(3) |
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
(1) |
Nov
(1) |
Dec
|
| 2014 |
Jan
(2) |
Feb
(2) |
Mar
(2) |
Apr
(3) |
May
(3) |
Jun
(1) |
Jul
|
Aug
(4) |
Sep
|
Oct
(1) |
Nov
(1) |
Dec
|
| 2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
(1) |
Dec
(1) |
| 2016 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
(1) |
Jul
|
Aug
(3) |
Sep
|
Oct
|
Nov
(1) |
Dec
|
| 2017 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <svn...@os...> - 2012-01-17 17:15:00
|
Author: aaime
Date: 2012-01-17 09:14:52 -0800 (Tue, 17 Jan 2012)
New Revision: 38499
Added:
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureReaderTest.java
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureSourceExposePkTest.java
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreExposedPkTest.java
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerLobTest.java
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerLobTestSetup.java
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerNoPrimaryKeyTest.java
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerNoPrimaryKeyTestSetup.java
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerSkipColumnTest.java
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerSkipColumnTestSetup.java
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerViewTest.java
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerViewTestSetup.java
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerVirtualTableTest.java
Modified:
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerDataStoreAPITestSetup.java
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerJoinTestSetup.java
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerPrimaryKeyTestSetup.java
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java
Log:
[GEOT-4021] Increase test coverage for SQL server store
Modified: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java 2012-01-17 17:14:14 UTC (rev 38498)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java 2012-01-17 17:14:52 UTC (rev 38499)
@@ -370,4 +370,19 @@
}
}
+ @Override
+ public void encodeValue(Object value, Class type, StringBuffer sql) {
+ if(byte[].class.equals(type)) {
+ byte[] b = (byte[]) value;
+
+ //encode as hex string
+ sql.append("0x");
+ for (int i=0; i < b.length; i++) {
+ sql.append(Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 ));
+ }
+ } else {
+ super.encodeValue(value, type, sql);
+ }
+ }
+
}
Modified: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerDataStoreAPITestSetup.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerDataStoreAPITestSetup.java 2012-01-17 17:14:14 UTC (rev 38498)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerDataStoreAPITestSetup.java 2012-01-17 17:14:52 UTC (rev 38499)
@@ -39,6 +39,8 @@
+ "geometry::STGeomFromText('LINESTRING(3 0, 3 2, 3 3, 3 4)',4326)," + "'r2')");
run("INSERT INTO road (id,geom,name) VALUES ( 2,"
+ "geometry::STGeomFromText('LINESTRING(3 2, 4 2, 5 3)',4326)," + "'r3')");
+
+ run("CREATE SPATIAL INDEX _road_geometry_index on road(geom) WITH (BOUNDING_BOX = (-10, -10, 10, 10))");
}
@Override
@@ -51,6 +53,8 @@
+ "'rv1', 4.5)");
run("INSERT INTO river (id,geom,river, flow) VALUES ( 1,"
+ "geometry::STGeomFromText('MULTILINESTRING((4 6, 4 8, 6 10))',4326)," + "'rv2', 3.0)");
+
+ run("CREATE SPATIAL INDEX _river_geometry_index on river(geom) WITH (BOUNDING_BOX = (-10, -10, 10, 10))");
}
@Override
@@ -60,6 +64,8 @@
run("INSERT INTO lake (id,geom,name) VALUES ( 0,"
+ "geometry::STGeomFromText('POLYGON((12 6, 14 8, 16 6, 16 4, 14 4, 12 6))',4326)," + "'muddy')");
+
+ run("CREATE SPATIAL INDEX _lake_geometry_index on lake(geom) WITH (BOUNDING_BOX = (-100, -100, 100, 100))");
}
@Override
Added: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureReaderTest.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureReaderTest.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureReaderTest.java 2012-01-17 17:14:52 UTC (rev 38499)
@@ -0,0 +1,13 @@
+package org.geotools.data.sqlserver;
+
+import org.geotools.jdbc.JDBCFeatureReaderTest;
+import org.geotools.jdbc.JDBCTestSetup;
+
+public class SQLServerFeatureReaderTest extends JDBCFeatureReaderTest {
+
+ @Override
+ protected JDBCTestSetup createTestSetup() {
+ return new SQLServerTestSetup();
+ }
+
+}
Added: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureSourceExposePkTest.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureSourceExposePkTest.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureSourceExposePkTest.java 2012-01-17 17:14:52 UTC (rev 38499)
@@ -0,0 +1,13 @@
+package org.geotools.data.sqlserver;
+
+import org.geotools.jdbc.JDBCFeatureSourceExposePkTest;
+import org.geotools.jdbc.JDBCTestSetup;
+
+public class SQLServerFeatureSourceExposePkTest extends JDBCFeatureSourceExposePkTest {
+
+ @Override
+ protected JDBCTestSetup createTestSetup() {
+ return new SQLServerTestSetup();
+ }
+
+}
Added: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreExposedPkTest.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreExposedPkTest.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreExposedPkTest.java 2012-01-17 17:14:52 UTC (rev 38499)
@@ -0,0 +1,63 @@
+package org.geotools.data.sqlserver;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.geotools.data.Transaction;
+import org.geotools.jdbc.JDBCFeatureStoreExposePkTest;
+import org.geotools.jdbc.JDBCTestSetup;
+
+public class SQLServerFeatureStoreExposedPkTest extends JDBCFeatureStoreExposePkTest {
+
+ @Override
+ protected JDBCTestSetup createTestSetup() {
+ return new SQLServerTestSetup();
+ }
+
+ @Override
+ public void testAddInTransaction() throws IOException {
+ // does not work, see GEOT-2832
+ }
+
+ public void testAddFeaturesUseProvidedFid() throws IOException {
+ // cannot work in general since the primary column is an identity:
+ // - it is not possible to insert into an indentity column unless the IDENTITY_INSERT
+ // property is set on it
+ // - however if IDENTITY_INSERT is setup, then the column stops generating values and
+ // requires one to insert values manually, which breaks other tests
+ }
+
+ @Override
+ public void testExternalConnection() throws IOException, SQLException {
+ // MVCC is not enabled by default in SQL Server, to do that one has to
+ // use something like:
+ // ALTER DATABASE ' + DB_NAME() + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE ;
+ // ALTER DATABASE ' + DB_NAME() + ' SET READ_COMMITTED_SNAPSHOT ON;
+ // ALTER DATABASE ' + DB_NAME() + ' SET MULTI_USER;'
+ // However this requires having admin access to the database, so we cannot
+ // assume we can run it, thus we just check if it's possible at all
+ // When the above is set the test passes, verified against SQL Server 2008
+
+ Connection cx = null;
+ Statement st = null;
+ ResultSet rs = null;
+ try {
+ cx = dataStore.getConnection(Transaction.AUTO_COMMIT);
+ st = cx.createStatement();
+ rs = st.executeQuery("SELECT is_read_committed_snapshot_on FROM sys.databases WHERE name= db_name()");
+ if(rs.next()) {
+ if(rs.getBoolean(1)) {
+ super.testExternalConnection();
+ }
+ }
+ } finally {
+ dataStore.closeSafe(rs);
+ dataStore.closeSafe(st);
+ dataStore.closeSafe(cx);
+ }
+
+ }
+}
Modified: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerJoinTestSetup.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerJoinTestSetup.java 2012-01-17 17:14:14 UTC (rev 38498)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerJoinTestSetup.java 2012-01-17 17:14:52 UTC (rev 38499)
@@ -28,12 +28,14 @@
protected void createJoinTable() throws Exception {
run( "CREATE TABLE ftjoin ( id int, name VARCHAR(10), geom GEOMETRY)" );
- //run("CALL AddGeometryColumn('geotools', 'ftjoin', 'geom', 4326, 'GEOMETRY', 2)");
run("ALTER TABLE ftjoin ALTER COLUMN name VARCHAR(255) COLLATE Latin1_General_CS_AS");
run( "INSERT INTO ftjoin VALUES (0, 'zero', geometry::STGeomFromText('POLYGON ((-0.1 -0.1, -0.1 0.1, 0.1 0.1, 0.1 -0.1, -0.1 -0.1))', 4326))");
run( "INSERT INTO ftjoin VALUES (1, 'one', geometry::STGeomFromText('POLYGON ((-1.1 -1.1, -1.1 1.1, 1.1 1.1, 1.1 -1.1, -1.1 -1.1))', 4326))");
run( "INSERT INTO ftjoin VALUES (2, 'two', geometry::STGeomFromText('POLYGON ((-10 -10, -10 10, 10 10, 10 -10, -10 -10))', 4326))");
run( "INSERT INTO ftjoin VALUES (3, 'three', NULL)");
+
+ // won't work in sql server since the table has no primary key
+ // run("CREATE SPATIAL INDEX _ftjoin_geometry_index on ftjoin(geom) WITH (BOUNDING_BOX = (-10, -10, 10, 10))");
}
@Override
Added: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerLobTest.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerLobTest.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerLobTest.java 2012-01-17 17:14:52 UTC (rev 38499)
@@ -0,0 +1,13 @@
+package org.geotools.data.sqlserver;
+
+import org.geotools.jdbc.JDBCLobTest;
+import org.geotools.jdbc.JDBCLobTestSetup;
+
+public class SQLServerLobTest extends JDBCLobTest {
+
+ @Override
+ protected JDBCLobTestSetup createTestSetup() {
+ return new SQLServerLobTestSetup(new SQLServerTestSetup());
+ }
+
+}
Added: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerLobTestSetup.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerLobTestSetup.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerLobTestSetup.java 2012-01-17 17:14:52 UTC (rev 38499)
@@ -0,0 +1,37 @@
+package org.geotools.data.sqlserver;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+
+import org.geotools.jdbc.JDBCLobTestSetup;
+import org.geotools.jdbc.JDBCTestSetup;
+
+public class SQLServerLobTestSetup extends JDBCLobTestSetup {
+
+ protected SQLServerLobTestSetup(JDBCTestSetup delegate) {
+ super(delegate);
+ }
+
+ @Override
+ protected void createLobTable() throws Exception {
+
+ Connection con = getDataSource().getConnection();
+ con.prepareStatement("create table \"testlob\" (\"fid\" int identity(0, 1) primary key, " +
+ "\"blob_field\" VARBINARY(50), \"clob_field\" TEXT, \"raw_field\" VARBINARY(50))").execute();
+
+ PreparedStatement ps =con.prepareStatement( "INSERT INTO \"testlob\" (\"blob_field\",\"clob_field\",\"raw_field\") VALUES (?,?,?)");
+ ps.setBytes(1, new byte[] {1,2,3,4,5});
+ ps.setString(2, "small clob");
+ ps.setBytes(3, new byte[] {6,7,8,9,10});
+ ps.execute();
+ ps.close();
+ con.close();
+ }
+
+ @Override
+ protected void dropLobTable() throws Exception {
+ runSafe("DROP TABLE \"testlob\"");
+ }
+
+
+}
Added: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerNoPrimaryKeyTest.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerNoPrimaryKeyTest.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerNoPrimaryKeyTest.java 2012-01-17 17:14:52 UTC (rev 38499)
@@ -0,0 +1,13 @@
+package org.geotools.data.sqlserver;
+
+import org.geotools.jdbc.JDBCNoPrimaryKeyTest;
+import org.geotools.jdbc.JDBCNoPrimaryKeyTestSetup;
+
+public class SQLServerNoPrimaryKeyTest extends JDBCNoPrimaryKeyTest {
+
+ @Override
+ protected JDBCNoPrimaryKeyTestSetup createTestSetup() {
+ return new SQLServerNoPrimaryKeyTestSetup(new SQLServerTestSetup());
+ }
+
+}
Added: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerNoPrimaryKeyTestSetup.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerNoPrimaryKeyTestSetup.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerNoPrimaryKeyTestSetup.java 2012-01-17 17:14:52 UTC (rev 38499)
@@ -0,0 +1,30 @@
+package org.geotools.data.sqlserver;
+
+import org.geotools.jdbc.JDBCNoPrimaryKeyTestSetup;
+import org.geotools.jdbc.JDBCTestSetup;
+
+public class SQLServerNoPrimaryKeyTestSetup extends JDBCNoPrimaryKeyTestSetup {
+
+ protected SQLServerNoPrimaryKeyTestSetup(JDBCTestSetup delegate) {
+ super(delegate);
+ }
+
+ @Override
+ protected void createLakeTable() throws Exception {
+ run("CREATE TABLE \"lake\"(\"id\" int, "
+ + "\"geom\" geometry, \"name\" varchar(255) )");
+
+ run("INSERT INTO \"lake\" (\"id\",\"geom\",\"name\") VALUES (0,"
+ + "geometry::STGeomFromText('POLYGON((12 6, 14 8, 16 6, 16 4, 14 4, 12 6))',4326),"
+ + "'muddy')");
+
+ // can't do this, sql server requires a primary key to use spatial indexes
+ // run("CREATE SPATIAL INDEX _lake_geometry_index on lake(geom) WITH (BOUNDING_BOX = (-10, -10, 10, 10))");
+ }
+
+ @Override
+ protected void dropLakeTable() throws Exception {
+ runSafe("DROP TABLE \"lake\"");
+ }
+
+}
Modified: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerPrimaryKeyTestSetup.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerPrimaryKeyTestSetup.java 2012-01-17 17:14:14 UTC (rev 38498)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerPrimaryKeyTestSetup.java 2012-01-17 17:14:52 UTC (rev 38499)
@@ -37,6 +37,8 @@
run( "INSERT INTO auto (name,geom ) VALUES ('one',geometry::STGeomFromText('POINT(1 1)',4326))");
run( "INSERT INTO auto (name,geom ) VALUES ('two',geometry::STGeomFromText('POINT(2 2)',4326))");
run( "INSERT INTO auto (name,geom ) VALUES ('three',geometry::STGeomFromText('POINT(3 3)',4326))");
+
+ run("CREATE SPATIAL INDEX _auto_geometry_index on auto(geom) WITH (BOUNDING_BOX = (-10, -10, 10, 10))");
}
@Override
@@ -51,6 +53,8 @@
run( "INSERT INTO noninc VALUES (1, 'one', geometry::STGeomFromText('POINT(1 1)',4326))");
run( "INSERT INTO noninc VALUES (2, 'two', geometry::STGeomFromText('POINT(2 2)',4326))");
run( "INSERT INTO noninc VALUES (3, 'three', geometry::STGeomFromText('POINT(3 3)',4326))");
+
+ run("CREATE SPATIAL INDEX _noninc_geometry_index on noninc(geom) WITH (BOUNDING_BOX = (-10, -10, 10, 10))");
}
@Override
@@ -62,6 +66,8 @@
run( "INSERT INTO multi VALUES (1, 'x', 'one', geometry::STGeomFromText('POINT(1 1)',4326))");
run( "INSERT INTO multi VALUES (2, 'y', 'two', geometry::STGeomFromText('POINT(2 2)',4326))");
run( "INSERT INTO multi VALUES (3, 'z', 'three', geometry::STGeomFromText('POINT(3 3)',4326))");
+
+ run("CREATE SPATIAL INDEX _multi_geometry_index on multi(geom) WITH (BOUNDING_BOX = (-10, -10, 10, 10))");
}
@Override
@@ -80,6 +86,9 @@
run( "INSERT INTO uniq VALUES (1, 'one',geometry::STGeomFromText('POINT(1 1)',4326))");
run( "INSERT INTO uniq VALUES (2, 'two',geometry::STGeomFromText('POINT(2 2)',4326))");
run( "INSERT INTO uniq VALUES (3, 'three',geometry::STGeomFromText('POINT(3 3)',4326))");
+
+ // spatial indexes in sql server require a primary key
+ // run("CREATE SPATIAL INDEX _uniq_geometry_index on uniq(geom) WITH (BOUNDING_BOX = (-10, -10, 10, 10))");
}
@Override
Added: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerSkipColumnTest.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerSkipColumnTest.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerSkipColumnTest.java 2012-01-17 17:14:52 UTC (rev 38499)
@@ -0,0 +1,22 @@
+package org.geotools.data.sqlserver;
+
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.jdbc.JDBCSkipColumnTest;
+import org.geotools.jdbc.JDBCSkipColumnTestSetup;
+
+public class SQLServerSkipColumnTest extends JDBCSkipColumnTest {
+
+ @Override
+ protected JDBCSkipColumnTestSetup createTestSetup() {
+ return new SQLServerSkipColumnTestSetup();
+ }
+
+ public void testGetBounds() throws Exception {
+ // sql server does not return empty bounds for a single point, but a very smal one instead
+ ReferencedEnvelope env = dataStore.getFeatureSource(tname(SKIPCOLUMN)).getBounds();
+ assertEquals(0.0, env.getMinX(), 1e-6);
+ assertEquals(0.0, env.getMinY(), 1e-6);
+ assertEquals(0.0, env.getMaxX(), 1e-6);
+ assertEquals(0.0, env.getMaxY(), 1e-6);
+ }
+}
Added: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerSkipColumnTestSetup.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerSkipColumnTestSetup.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerSkipColumnTestSetup.java 2012-01-17 17:14:52 UTC (rev 38499)
@@ -0,0 +1,28 @@
+package org.geotools.data.sqlserver;
+
+import org.geotools.jdbc.JDBCSkipColumnTestSetup;
+
+public class SQLServerSkipColumnTestSetup extends JDBCSkipColumnTestSetup {
+
+ protected SQLServerSkipColumnTestSetup() {
+ super(new SQLServerTestSetup());
+ }
+
+ @Override
+ protected void createSkipColumnTable() throws Exception {
+ run("CREATE TABLE \"skipcolumn\"(" //
+ + "\"fid\" int identity(0, 1) primary key, " //
+ + "\"id\" integer, " //
+ + "\"geom\" geometry, " //
+ + "\"weirdproperty\" xml," //
+ + "\"name\" varchar(255))");
+ run("INSERT INTO \"skipcolumn\" VALUES( 0, geometry::STGeomFromText('POINT(0 0)', 4326), null, 'GeoTools')");
+ }
+
+ @Override
+ protected void dropSkipColumnTable() throws Exception {
+ runSafe("DELETE FROM GEOMETRY_COLUMNS WHERE F_TABLE_NAME = 'skipcolumn'");
+ runSafe("DROP TABLE \"skipcolumn\"");
+ }
+
+}
Modified: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java 2012-01-17 17:14:14 UTC (rev 38498)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java 2012-01-17 17:14:52 UTC (rev 38499)
@@ -86,6 +86,9 @@
sql = "INSERT INTO ft1 (geometry,intProperty,doubleProperty,stringProperty) VALUES ("
+ "geometry::STGeomFromText('POINT(2 2)',4326), 2, 2.2,'two');";
run(sql);
+
+ // create the spatial index
+ run("CREATE SPATIAL INDEX _ft1_geometry_index on ft1(geometry) WITH (BOUNDING_BOX = (-10, -10, 10, 10))");
}
@Override
Added: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerViewTest.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerViewTest.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerViewTest.java 2012-01-17 17:14:52 UTC (rev 38499)
@@ -0,0 +1,41 @@
+package org.geotools.data.sqlserver;
+
+import org.geotools.jdbc.JDBCViewTest;
+import org.geotools.jdbc.JDBCViewTestSetup;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.AttributeType;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+public class SQLServerViewTest extends JDBCViewTest {
+
+ @Override
+ protected JDBCViewTestSetup createTestSetup() {
+ return new SQLServerViewTestSetup();
+ }
+
+
+ /**
+ * Override since sql server metadata over nullability over views works differently than in other databases
+ */
+ protected void assertAttributesEqual(AttributeDescriptor expected, AttributeDescriptor actual) {
+ assertEquals(aname(expected.getName()), actual.getName());
+ // assertEquals(expected.getMinOccurs(), actual.getMinOccurs());
+ assertEquals(expected.getMaxOccurs(), actual.getMaxOccurs());
+ // assertEquals(expected.isNillable(), actual.isNillable());
+ assertEquals(expected.getDefaultValue(), actual.getDefaultValue());
+
+ AttributeType texpected = expected.getType();
+ AttributeType tactual = actual.getType();
+
+ if ( Number.class.isAssignableFrom( texpected.getBinding() ) ) {
+ assertTrue( Number.class.isAssignableFrom( tactual.getBinding() ) );
+ }
+ else if ( Geometry.class.isAssignableFrom( texpected.getBinding())) {
+ assertTrue( Geometry.class.isAssignableFrom( tactual.getBinding()));
+ }
+ else {
+ assertTrue(texpected.getBinding().isAssignableFrom(tactual.getBinding()));
+ }
+ }
+}
Added: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerViewTestSetup.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerViewTestSetup.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerViewTestSetup.java 2012-01-17 17:14:52 UTC (rev 38499)
@@ -0,0 +1,50 @@
+package org.geotools.data.sqlserver;
+
+import org.geotools.jdbc.JDBCViewTestSetup;
+
+public class SQLServerViewTestSetup extends JDBCViewTestSetup {
+
+ protected SQLServerViewTestSetup() {
+ super(new SQLServerTestSetup());
+ }
+
+ @Override
+ protected void createLakesTable() throws Exception {
+ run("CREATE TABLE lakes(fid int IDENTITY(0,1) PRIMARY KEY, id int, "
+ + "geom geometry, name varchar(255) )");
+
+ run("INSERT INTO lakes (id,geom,name) VALUES ( 0,"
+ + "geometry::STGeomFromText('POLYGON((12 6, 14 8, 16 6, 16 4, 14 4, 12 6))',4326),"
+ + "'muddy')");
+
+ run("CREATE SPATIAL INDEX _lakes_geometry_index on lakes(geom) WITH (BOUNDING_BOX = (-100, -100, 100, 100))");
+ }
+
+ @Override
+ protected void dropLakesTable() throws Exception {
+ runSafe("DROP TABLE \"lakes\"");
+ }
+
+ @Override
+ protected void createLakesView() throws Exception {
+ run("create view \"lakesview\" as select * from \"lakes\"");
+ }
+
+ @Override
+ protected void dropLakesView() throws Exception {
+ runSafe("DROP VIEW \"lakesview\"");
+ }
+
+ @Override
+ protected void createLakesViewPk() throws Exception {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ protected void dropLakesViewPk() throws Exception {
+ // TODO Auto-generated method stub
+
+ }
+
+}
Added: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerVirtualTableTest.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerVirtualTableTest.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerVirtualTableTest.java 2012-01-17 17:14:52 UTC (rev 38499)
@@ -0,0 +1,14 @@
+package org.geotools.data.sqlserver;
+
+import org.geotools.jdbc.JDBCDataStoreAPITestSetup;
+import org.geotools.jdbc.JDBCVirtualTableTest;
+
+
+public class SQLServerVirtualTableTest extends JDBCVirtualTableTest {
+
+ @Override
+ protected JDBCDataStoreAPITestSetup createTestSetup() {
+ return new SQLServerDataStoreAPITestSetup();
+ }
+
+}
|
|
From: <svn...@os...> - 2012-01-17 17:14:25
|
Author: aaime
Date: 2012-01-17 09:14:14 -0800 (Tue, 17 Jan 2012)
New Revision: 38498
Modified:
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java
Log:
[GEOT-4019] Support native paging in sql server
Modified: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java 2012-01-17 17:13:55 UTC (rev 38497)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java 2012-01-17 17:14:14 UTC (rev 38498)
@@ -329,4 +329,45 @@
}
}
+ @Override
+ public boolean isLimitOffsetSupported() {
+ return true;
+ }
+
+ @Override
+ public void applyLimitOffset(StringBuffer sql, int limit, int offset) {
+ // if we have a nested query (used in sql views) we might have a inner order by,
+ // check for the last closed )
+ int lastClosed = sql.lastIndexOf(")");
+ int orderByIndex = sql.lastIndexOf("ORDER BY");
+ CharSequence orderBy;
+ if(orderByIndex > 0 && orderByIndex > lastClosed) {
+ // we'll move the order by into the ROW_NUMBER call
+ orderBy = sql.subSequence(orderByIndex, sql.length());
+ sql.delete(orderByIndex, orderByIndex + orderBy.length());
+ } else {
+ // ROW_NUMBER requires an order by clause, we need to feed it something
+ orderBy = "ORDER BY CURRENT_TIMESTAMP";
+ }
+
+ // now insert the order by inside the select
+ int fromStart = sql.indexOf("FROM");
+ sql.insert(fromStart - 1, ", ROW_NUMBER() OVER (" + orderBy + ") AS _GT_ROW_NUMBER ");
+
+ // and wrap inside a block that selects the portion we want
+ sql.insert(0, "SELECT * FROM (");
+ sql.append(") AS _GT_PAGING_SUBQUERY WHERE ");
+ if(offset > 0) {
+ sql.append("_GT_ROW_NUMBER > " + offset);
+ }
+ if(limit >= 0 && limit < Integer.MAX_VALUE) {
+ int max = limit;
+ if(offset > 0) {
+ max += offset;
+ sql.append(" AND ");
+ }
+ sql.append("_GT_ROW_NUMBER <= " + max);
+ }
+ }
+
}
|
|
From: <svn...@os...> - 2012-01-17 17:14:05
|
Author: aaime
Date: 2012-01-17 09:13:55 -0800 (Tue, 17 Jan 2012)
New Revision: 38497
Modified:
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java
Log:
[GEOT-4020] Have SQL server store use WKB for geometry transfers
Modified: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java 2012-01-16 18:26:12 UTC (rev 38496)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java 2012-01-17 17:13:55 UTC (rev 38497)
@@ -42,6 +42,7 @@
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.io.ParseException;
+import com.vividsolutions.jts.io.WKBReader;
import com.vividsolutions.jts.io.WKTReader;
/**
@@ -59,7 +60,7 @@
public SQLServerDialect(JDBCDataStore dataStore) {
super(dataStore);
}
-
+
@Override
public boolean includeTable(String schemaName, String tableName,
Connection cx) throws SQLException {
@@ -184,17 +185,8 @@
@Override
public void encodeGeometryColumn(GeometryDescriptor gatt, String prefix, int srid, StringBuffer sql) {
- sql.append( "CAST(");
encodeColumnName( prefix, gatt.getLocalName(), sql );
- sql.append( ".STSrid as VARCHAR)");
-
- sql.append( " + ':' + " );
-
- encodeColumnName( prefix, gatt.getLocalName(), sql );
- sql.append( ".STAsText()");
-
- //encodeColumnName(gatt.getLocalName(), sql);
- //sql.append( ".STAsText()");
+ sql.append( ".STAsBinary()");
}
@Override
@@ -213,8 +205,15 @@
public Geometry decodeGeometryValue(GeometryDescriptor descriptor,
ResultSet rs, String column, GeometryFactory factory, Connection cx)
throws IOException, SQLException {
- String s = rs.getString( column );
- return decodeGeometry ( s, factory );
+ byte[] bytes = rs.getBytes(column);
+ if(bytes == null) {
+ return null;
+ }
+ try {
+ return new WKBReader(factory).read(bytes);
+ } catch ( ParseException e ) {
+ throw (IOException) new IOException().initCause( e );
+ }
}
Geometry decodeGeometry( String s, GeometryFactory factory ) throws IOException {
@@ -329,4 +328,5 @@
sql.append(tableName);
}
}
+
}
|
|
From: <svn...@os...> - 2012-01-16 18:26:22
|
Author: aaime
Date: 2012-01-16 10:26:12 -0800 (Mon, 16 Jan 2012)
New Revision: 38496
Modified:
branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDataStoreFactory.java
branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java
Log:
[GEOT-4016] Add validation query to sql server store
Modified: branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDataStoreFactory.java
===================================================================
--- branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDataStoreFactory.java 2012-01-16 18:25:49 UTC (rev 38495)
+++ branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDataStoreFactory.java 2012-01-16 18:26:12 UTC (rev 38496)
@@ -59,8 +59,7 @@
@Override
protected String getValidationQuery() {
- // no known way to validate a connection, if you know any, please advise
- return null;
+ return "select 1";
}
@SuppressWarnings("unchecked")
@@ -91,4 +90,5 @@
return url;
}
+
}
Modified: branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java
===================================================================
--- branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java 2012-01-16 18:25:49 UTC (rev 38495)
+++ branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java 2012-01-16 18:26:12 UTC (rev 38496)
@@ -18,6 +18,7 @@
import java.util.Properties;
+import org.apache.commons.dbcp.BasicDataSource;
import org.geotools.jdbc.JDBCDataStore;
import org.geotools.jdbc.JDBCDataStoreFactory;
import org.geotools.jdbc.JDBCTestSetup;
@@ -81,5 +82,11 @@
+ "geometry::STGeomFromText('POINT(2 2)',4326), 2, 2.2,'two');";
run(sql);
}
+
+ @Override
+ protected void initializeDataSource(BasicDataSource ds, Properties db) {
+ super.initializeDataSource(ds, db);
+ ds.setValidationQuery("select 1");
+ }
}
|
|
From: <svn...@os...> - 2012-01-16 18:25:55
|
Author: aaime
Date: 2012-01-16 10:25:49 -0800 (Mon, 16 Jan 2012)
New Revision: 38495
Modified:
branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreTest.java
Log:
[GEOT-4015] SQLServerFeatureStore locks up on testExternalConnection since SQLServer does not support MVCC by default
Modified: branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreTest.java
===================================================================
--- branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreTest.java 2012-01-16 18:25:24 UTC (rev 38494)
+++ branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreTest.java 2012-01-16 18:25:49 UTC (rev 38495)
@@ -17,7 +17,12 @@
package org.geotools.data.sqlserver;
import java.io.IOException;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import org.geotools.data.Transaction;
import org.geotools.jdbc.JDBCFeatureStoreTest;
import org.geotools.jdbc.JDBCTestSetup;
@@ -40,5 +45,36 @@
// - however if IDENTITY_INSERT is setup, then the column stops generating values and
// requires one to insert values manually, which breaks other tests
}
+
+ @Override
+ public void testExternalConnection() throws IOException, SQLException {
+ // MVCC is not enabled by default in SQL Server, to do that one has to
+ // use something like:
+ // ALTER DATABASE ' + DB_NAME() + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE ;
+ // ALTER DATABASE ' + DB_NAME() + ' SET READ_COMMITTED_SNAPSHOT ON;
+ // ALTER DATABASE ' + DB_NAME() + ' SET MULTI_USER;'
+ // However this requires having admin access to the database, so we cannot
+ // assume we can run it, thus we just check if it's possible at all
+ // When the above is set the test passes, verified against SQL Server 2008
+
+ Connection cx = null;
+ Statement st = null;
+ ResultSet rs = null;
+ try {
+ cx = dataStore.getConnection(Transaction.AUTO_COMMIT);
+ st = cx.createStatement();
+ rs = st.executeQuery("SELECT is_read_committed_snapshot_on FROM sys.databases WHERE name= db_name()");
+ if(rs.next()) {
+ if(rs.getBoolean(1)) {
+ super.testExternalConnection();
+ }
+ }
+ } finally {
+ dataStore.closeSafe(rs);
+ dataStore.closeSafe(st);
+ dataStore.closeSafe(cx);
+ }
+
+ }
}
|
|
From: <svn...@os...> - 2012-01-16 18:25:30
|
Author: aaime
Date: 2012-01-16 10:25:24 -0800 (Mon, 16 Jan 2012)
New Revision: 38494
Modified:
branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreTest.java
Log:
[GEOT-4014] SQLServerFeatureStoreTest.testAddFeaturesUseProvidedFid
Modified: branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreTest.java
===================================================================
--- branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreTest.java 2012-01-16 18:25:09 UTC (rev 38493)
+++ branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreTest.java 2012-01-16 18:25:24 UTC (rev 38494)
@@ -32,5 +32,13 @@
public void testAddInTransaction() throws IOException {
// does not work, see GEOT-2832
}
+
+ public void testAddFeaturesUseProvidedFid() throws IOException {
+ // cannot work in general since the primary column is an identity:
+ // - it is not possible to insert into an indentity column unless the IDENTITY_INSERT
+ // property is set on it
+ // - however if IDENTITY_INSERT is setup, then the column stops generating values and
+ // requires one to insert values manually, which breaks other tests
+ }
}
|
|
From: <svn...@os...> - 2012-01-16 18:25:20
|
Author: aaime
Date: 2012-01-16 10:25:09 -0800 (Mon, 16 Jan 2012)
New Revision: 38493
Modified:
branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java
Log:
[GEOT-4013] SQLServerFeatureCollectionTest.testIterator failing
Modified: branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java
===================================================================
--- branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java 2012-01-16 18:24:54 UTC (rev 38492)
+++ branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java 2012-01-16 18:25:09 UTC (rev 38493)
@@ -60,7 +60,7 @@
//create the data
- String sql = "CREATE TABLE ft1 (id int IDENTITY(1,1) PRIMARY KEY, "
+ String sql = "CREATE TABLE ft1 (id int IDENTITY(0,1) PRIMARY KEY, "
+ "geometry geometry, intProperty int, "
+ "doubleProperty float, stringProperty varchar(255))";
run(sql);
|
|
From: <svn...@os...> - 2012-01-16 18:25:04
|
Author: aaime Date: 2012-01-16 10:24:54 -0800 (Mon, 16 Jan 2012) New Revision: 38492 Modified: branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/README.txt branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/pom.xml Log: [GEOT-4010] Update instructions to install the SQL Server driver on trunk and 2.7.x Modified: branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/README.txt =================================================================== --- branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/README.txt 2012-01-16 15:40:54 UTC (rev 38491) +++ branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/README.txt 2012-01-16 18:24:54 UTC (rev 38492) @@ -4,13 +4,18 @@ JDBC Driver ----------- -To use the sql server datastore the jdbc driver must be downloaded from +To use the sql server datastore the jdbc 3.0 driver must be downloaded from Microsoft: - http://msdn.microsoft.com/en-us/data/aa937724.aspx + http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=19847 -The current tested driver version is 1.2 (SQL Server 2005). +The current tested driver version is 3.0 for SQL Server and SQL Azure. According to Microsoft this +driver provides access to SQL Azure, SQL Server 2008 R2, SQL Server 2008, SQL Server 2005 and +SQL Server 2000 from any Java application, application server, or Java-enabled applet. +Make sure to unpack the sqljdbc.jar file, as that's the one providing support for the Java +version in this series (Java 1.5) + Maven ----- @@ -21,7 +26,7 @@ mvn install:install-file -Dfile=<path to sqljdbc.jar> -DartifactId=sqljdbc \ -DgroupId=com.microsoft \ - -Dversion=1.2 \ + -Dversion=3.0 \ -Dpackaging=jar \ -DgeneratePom=true Modified: branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/pom.xml =================================================================== --- branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/pom.xml 2012-01-16 15:40:54 UTC (rev 38491) +++ branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/pom.xml 2012-01-16 18:24:54 UTC (rev 38492) @@ -63,6 +63,16 @@ <role>Java Developer</role> </roles> </developer> + <developer> + <name>Andrea Aime</name> + <id>aaime</id> + <email>and...@ge...</email> + <organization>GeoSolutions</organization> + <roles> + <role>Module Maintainer</role> + <role>Java Developer</role> + </roles> + </developer> </developers> <profiles> @@ -72,9 +82,13 @@ <dependency> <groupId>com.microsoft</groupId> <artifactId>sqljdbc</artifactId> - <version>1.2</version> + <version>${sqlServerDriverVersion}</version> </dependency> </dependencies> </profile> </profiles> + + <properties> + <sqlServerDriverVersion>3.0</sqlServerDriverVersion> + </properties> </project> |
|
From: <svn...@os...> - 2012-01-16 15:48:55
|
Author: aaime
Date: 2012-01-16 07:40:54 -0800 (Mon, 16 Jan 2012)
New Revision: 38491
Modified:
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDataStoreFactory.java
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java
Log:
[GEOT-4016] Add validation query to sql server store
Modified: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDataStoreFactory.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDataStoreFactory.java 2012-01-16 15:40:31 UTC (rev 38490)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDataStoreFactory.java 2012-01-16 15:40:54 UTC (rev 38491)
@@ -60,8 +60,7 @@
@Override
protected String getValidationQuery() {
- // no known way to validate a connection, if you know any, please advise
- return null;
+ return "select 1";
}
@SuppressWarnings("unchecked")
@@ -92,4 +91,5 @@
return url;
}
+
}
Modified: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java 2012-01-16 15:40:31 UTC (rev 38490)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java 2012-01-16 15:40:54 UTC (rev 38491)
@@ -18,6 +18,7 @@
import java.util.Properties;
+import org.apache.commons.dbcp.BasicDataSource;
import org.geotools.jdbc.JDBCDataStore;
import org.geotools.jdbc.JDBCDataStoreFactory;
import org.geotools.jdbc.JDBCTestSetup;
@@ -86,5 +87,11 @@
+ "geometry::STGeomFromText('POINT(2 2)',4326), 2, 2.2,'two');";
run(sql);
}
+
+ @Override
+ protected void initializeDataSource(BasicDataSource ds, Properties db) {
+ super.initializeDataSource(ds, db);
+ ds.setValidationQuery("select 1");
+ }
}
|
|
From: <svn...@os...> - 2012-01-16 15:40:37
|
Author: aaime
Date: 2012-01-16 07:40:31 -0800 (Mon, 16 Jan 2012)
New Revision: 38490
Modified:
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreTest.java
Log:
[GEOT-4015] SQLServerFeatureStore locks up on testExternalConnection since SQLServer does not support MVCC by default
Modified: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreTest.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreTest.java 2012-01-16 15:40:15 UTC (rev 38489)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreTest.java 2012-01-16 15:40:31 UTC (rev 38490)
@@ -17,7 +17,12 @@
package org.geotools.data.sqlserver;
import java.io.IOException;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import org.geotools.data.Transaction;
import org.geotools.jdbc.JDBCFeatureStoreTest;
import org.geotools.jdbc.JDBCTestSetup;
@@ -45,5 +50,36 @@
// - however if IDENTITY_INSERT is setup, then the column stops generating values and
// requires one to insert values manually, which breaks other tests
}
+
+ @Override
+ public void testExternalConnection() throws IOException, SQLException {
+ // MVCC is not enabled by default in SQL Server, to do that one has to
+ // use something like:
+ // ALTER DATABASE ' + DB_NAME() + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE ;
+ // ALTER DATABASE ' + DB_NAME() + ' SET READ_COMMITTED_SNAPSHOT ON;
+ // ALTER DATABASE ' + DB_NAME() + ' SET MULTI_USER;'
+ // However this requires having admin access to the database, so we cannot
+ // assume we can run it, thus we just check if it's possible at all
+ // When the above is set the test passes, verified against SQL Server 2008
+
+ Connection cx = null;
+ Statement st = null;
+ ResultSet rs = null;
+ try {
+ cx = dataStore.getConnection(Transaction.AUTO_COMMIT);
+ st = cx.createStatement();
+ rs = st.executeQuery("SELECT is_read_committed_snapshot_on FROM sys.databases WHERE name= db_name()");
+ if(rs.next()) {
+ if(rs.getBoolean(1)) {
+ super.testExternalConnection();
+ }
+ }
+ } finally {
+ dataStore.closeSafe(rs);
+ dataStore.closeSafe(st);
+ dataStore.closeSafe(cx);
+ }
+
+ }
}
|
|
From: <svn...@os...> - 2012-01-16 15:40:26
|
Author: aaime
Date: 2012-01-16 07:40:15 -0800 (Mon, 16 Jan 2012)
New Revision: 38489
Modified:
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreTest.java
Log:
[GEOT-4014] SQLServerFeatureStoreTest.testAddFeaturesUseProvidedFid
Modified: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreTest.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreTest.java 2012-01-16 15:40:00 UTC (rev 38488)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerFeatureStoreTest.java 2012-01-16 15:40:15 UTC (rev 38489)
@@ -37,5 +37,13 @@
public void testAddInTransaction() throws IOException {
// does not work, see GEOT-2832
}
+
+ public void testAddFeaturesUseProvidedFid() throws IOException {
+ // cannot work in general since the primary column is an identity:
+ // - it is not possible to insert into an indentity column unless the IDENTITY_INSERT
+ // property is set on it
+ // - however if IDENTITY_INSERT is setup, then the column stops generating values and
+ // requires one to insert values manually, which breaks other tests
+ }
}
|
|
From: <svn...@os...> - 2012-01-16 15:40:11
|
Author: aaime
Date: 2012-01-16 07:40:00 -0800 (Mon, 16 Jan 2012)
New Revision: 38488
Modified:
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java
Log:
[GEOT-4013] SQLServerFeatureCollectionTest.testIterator failing
Modified: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java 2012-01-16 15:39:46 UTC (rev 38487)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/test/java/org/geotools/data/sqlserver/SQLServerTestSetup.java 2012-01-16 15:40:00 UTC (rev 38488)
@@ -65,7 +65,7 @@
//create the data
- String sql = "CREATE TABLE ft1 (id int IDENTITY(1,1) PRIMARY KEY, "
+ String sql = "CREATE TABLE ft1 (id int IDENTITY(0,1) PRIMARY KEY, "
+ "geometry geometry, intProperty int, "
+ "doubleProperty float, stringProperty varchar(255))";
run(sql);
|
|
From: <svn...@os...> - 2012-01-16 15:39:55
|
Author: aaime
Date: 2012-01-16 07:39:46 -0800 (Mon, 16 Jan 2012)
New Revision: 38487
Modified:
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerFilterToSQL.java
Log:
[GEOT-4011] SQL server won't encode properly filters using literals other than dates
Modified: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerFilterToSQL.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerFilterToSQL.java 2012-01-16 15:39:31 UTC (rev 38486)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerFilterToSQL.java 2012-01-16 15:39:46 UTC (rev 38487)
@@ -190,6 +190,8 @@
protected void writeLiteral(Object literal) throws IOException {
if (literal instanceof Date) {
out.write("'" + DATETIME_FORMAT.format(literal) + "'");
+ } else {
+ super.writeLiteral(literal);
}
}
}
|
|
From: <svn...@os...> - 2012-01-16 15:39:39
|
Author: aaime Date: 2012-01-16 07:39:31 -0800 (Mon, 16 Jan 2012) New Revision: 38486 Modified: trunk/modules/plugin/jdbc/jdbc-sqlserver/README.txt trunk/modules/plugin/jdbc/jdbc-sqlserver/pom.xml Log: [GEOT-4010] Update instructions to install the SQL Server driver on trunk and 2.7.x Modified: trunk/modules/plugin/jdbc/jdbc-sqlserver/README.txt =================================================================== --- trunk/modules/plugin/jdbc/jdbc-sqlserver/README.txt 2012-01-15 20:06:03 UTC (rev 38485) +++ trunk/modules/plugin/jdbc/jdbc-sqlserver/README.txt 2012-01-16 15:39:31 UTC (rev 38486) @@ -4,13 +4,20 @@ JDBC Driver ----------- -To use the sql server datastore the jdbc driver must be downloaded from +To use the sql server datastore the jdbc 3.0 driver must be downloaded from Microsoft: - http://msdn.microsoft.com/en-us/data/aa937724.aspx + http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=19847 -The current tested driver version is 1.2 (SQL Server 2005). +The current tested driver version is 3.0 for SQL Server and SQL Azure. According to Microsoft this +driver provides access to SQL Azure, SQL Server 2008 R2, SQL Server 2008, SQL Server 2005 and +SQL Server 2000 from any Java application, application server, or Java-enabled applet. +Make sure to unpack the sqljdbc4.jar file, as that's the one providing support for the Java +version in this series. +If you are using Java 5 you should downgrade to GeoTools 2.7.x, while Java 7 is, at the time +of writing, not officially supported + Maven ----- @@ -18,10 +25,10 @@ 1. install the JDBC driver into the location maven repository: - mvn install:install-file -Dfile=<path to sqljdbc.jar> - -DartifactId=sqljdbc \ + mvn install:install-file -Dfile=<path to sqljdbc4.jar> + -DartifactId=sqljdbc4 \ -DgroupId=com.microsoft \ - -Dversion=1.2 \ + -Dversion=3.0 \ -Dpackaging=jar \ -DgeneratePom=true Modified: trunk/modules/plugin/jdbc/jdbc-sqlserver/pom.xml =================================================================== --- trunk/modules/plugin/jdbc/jdbc-sqlserver/pom.xml 2012-01-15 20:06:03 UTC (rev 38485) +++ trunk/modules/plugin/jdbc/jdbc-sqlserver/pom.xml 2012-01-16 15:39:31 UTC (rev 38486) @@ -63,6 +63,16 @@ <role>Java Developer</role> </roles> </developer> + <developer> + <name>Andrea Aime</name> + <id>aaime</id> + <email>and...@ge...</email> + <organization>GeoSolutions</organization> + <roles> + <role>Module Maintainer</role> + <role>Java Developer</role> + </roles> + </developer> </developers> <profiles> @@ -71,7 +81,7 @@ <dependencies> <dependency> <groupId>com.microsoft</groupId> - <artifactId>sqljdbc</artifactId> + <artifactId>sqljdbc4</artifactId> <version>${sqlServerDriverVersion}</version> </dependency> </dependencies> @@ -79,6 +89,6 @@ </profiles> <properties> - <sqlServerDriverVersion>4.0</sqlServerDriverVersion> + <sqlServerDriverVersion>3.0</sqlServerDriverVersion> </properties> </project> |
|
From: <svn...@os...> - 2012-01-15 20:06:10
|
Author: aaime Date: 2012-01-15 12:06:03 -0800 (Sun, 15 Jan 2012) New Revision: 38485 Added: branches/2.7.x/modules/library/main/src/test/resources/org/geotools/filter/test-data/crosses.xml Log: Forgot to commit a file for GEOT-4004 Added: branches/2.7.x/modules/library/main/src/test/resources/org/geotools/filter/test-data/crosses.xml =================================================================== --- branches/2.7.x/modules/library/main/src/test/resources/org/geotools/filter/test-data/crosses.xml (rev 0) +++ branches/2.7.x/modules/library/main/src/test/resources/org/geotools/filter/test-data/crosses.xml 2012-01-15 20:06:03 UTC (rev 38485) @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Filter xmlns:gml="http://www.opengis.net/gml"> + <Crosses> + <PropertyName>the_geom</PropertyName> + <gml:LineString srsName="http://www.opengis.net/gml/srs/EPSG#4326"> + <gml:coordinates>1.25,0.25 1.75,0.75</gml:coordinates> + </gml:LineString> + </Crosses> +</Filter> \ No newline at end of file |
|
From: <svn...@os...> - 2012-01-15 20:05:06
|
Author: aaime Date: 2012-01-15 12:04:59 -0800 (Sun, 15 Jan 2012) New Revision: 38484 Added: trunk/modules/library/main/src/test/resources/org/geotools/filter/test-data/crosses.xml Log: Forgot to commit a file for GEOT-4004 Added: trunk/modules/library/main/src/test/resources/org/geotools/filter/test-data/crosses.xml =================================================================== --- trunk/modules/library/main/src/test/resources/org/geotools/filter/test-data/crosses.xml (rev 0) +++ trunk/modules/library/main/src/test/resources/org/geotools/filter/test-data/crosses.xml 2012-01-15 20:04:59 UTC (rev 38484) @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Filter xmlns:gml="http://www.opengis.net/gml"> + <Crosses> + <PropertyName>the_geom</PropertyName> + <gml:LineString srsName="http://www.opengis.net/gml/srs/EPSG#4326"> + <gml:coordinates>1.25,0.25 1.75,0.75</gml:coordinates> + </gml:LineString> + </Crosses> +</Filter> \ No newline at end of file |
|
From: <svn...@os...> - 2012-01-15 18:26:08
|
Author: aaime
Date: 2012-01-15 10:26:02 -0800 (Sun, 15 Jan 2012)
New Revision: 38483
Modified:
trunk/modules/library/main/src/main/java/org/geotools/filter/FilterDOMParser.java
trunk/modules/library/main/src/main/java/org/geotools/filter/GeometryFilterImpl.java
trunk/modules/library/main/src/test/java/org/geotools/filter/DOMParserTest.java
Log:
[GEOT-4004] FilterDomParser handles Crosses as Touches (patch by Jan De Moerloose)
Modified: trunk/modules/library/main/src/main/java/org/geotools/filter/FilterDOMParser.java
===================================================================
--- trunk/modules/library/main/src/main/java/org/geotools/filter/FilterDOMParser.java 2012-01-15 18:25:20 UTC (rev 38482)
+++ trunk/modules/library/main/src/main/java/org/geotools/filter/FilterDOMParser.java 2012-01-15 18:26:02 UTC (rev 38483)
@@ -469,7 +469,7 @@
return FILTER_FACT.touches( left, right );
case FilterType.GEOMETRY_CROSSES:
- return FILTER_FACT.touches( left, right );
+ return FILTER_FACT.crosses( left, right );
case FilterType.GEOMETRY_WITHIN:
return FILTER_FACT.within( left, right );
Modified: trunk/modules/library/main/src/main/java/org/geotools/filter/GeometryFilterImpl.java
===================================================================
--- trunk/modules/library/main/src/main/java/org/geotools/filter/GeometryFilterImpl.java 2012-01-15 18:25:20 UTC (rev 38482)
+++ trunk/modules/library/main/src/main/java/org/geotools/filter/GeometryFilterImpl.java 2012-01-15 18:26:02 UTC (rev 38483)
@@ -289,6 +289,8 @@
operator = " disjoint ";
} else if (filterType == GEOMETRY_INTERSECTS) {
operator = " intersects ";
+ } else if (filterType == GEOMETRY_TOUCHES) {
+ operator = " touches ";
} else if (filterType == GEOMETRY_CROSSES) {
operator = " crosses ";
} else if (filterType == GEOMETRY_WITHIN) {
Modified: trunk/modules/library/main/src/test/java/org/geotools/filter/DOMParserTest.java
===================================================================
--- trunk/modules/library/main/src/test/java/org/geotools/filter/DOMParserTest.java 2012-01-15 18:25:20 UTC (rev 38482)
+++ trunk/modules/library/main/src/test/java/org/geotools/filter/DOMParserTest.java 2012-01-15 18:26:02 UTC (rev 38483)
@@ -34,6 +34,7 @@
import org.opengis.filter.expression.Literal;
import org.opengis.filter.expression.PropertyName;
import org.opengis.filter.spatial.Beyond;
+import org.opengis.filter.spatial.Crosses;
import org.opengis.filter.spatial.DWithin;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -42,6 +43,7 @@
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.Point;
/**
@@ -237,6 +239,15 @@
LOGGER.fine("parsed filter is " + test);
}
+ public void testCrosses() throws Exception {
+ Filter test = parseDocument("crosses.xml");
+ assertTrue(test instanceof Crosses);
+ Crosses cr = (Crosses) test;
+ assertEquals("the_geom", ((PropertyName) cr.getExpression1()).getPropertyName());
+ assertTrue(((Literal) cr.getExpression2()).getValue() instanceof LineString);
+ LOGGER.fine("parsed filter is " + test);
+ }
+
public void test28() throws Exception {
FidFilter filter = (FidFilter) parseDocumentFirst("test28.xml");
String[] fids = filter.getFids();
|
|
From: <svn...@os...> - 2012-01-15 18:25:31
|
Author: aaime Date: 2012-01-15 10:25:20 -0800 (Sun, 15 Jan 2012) New Revision: 38482 Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FeatureTypeMapper.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FilterToRestrictedWhere.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/GdalInit.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFeatureStore.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFilterTranslator.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRUtils.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/BridjUtilities.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/CplErrorLibrary.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/OGREnvelope.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/OGRField.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/OgrLibrary.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/OsrLibrary.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/__locale_struct.java Log: Whoops, forgot to commit some files Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FeatureTypeMapper.java =================================================================== --- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FeatureTypeMapper.java (rev 0) +++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FeatureTypeMapper.java 2012-01-15 18:25:20 UTC (rev 38482) @@ -0,0 +1,376 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2007-2008, Open Source Geospatial Foundation (OSGeo) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package org.geotools.data.ogr; + +import static org.bridj.Pointer.*; +import static org.geotools.data.ogr.bridj.OgrLibrary.*; +import static org.geotools.data.ogr.bridj.OsrLibrary.*; + +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.bridj.Pointer; +import org.bridj.ValuedEnum; +import org.geotools.data.ogr.bridj.OgrLibrary.OGRFieldType; +import org.geotools.data.ogr.bridj.OgrLibrary.OGRJustification; +import org.geotools.data.ogr.bridj.OgrLibrary.OGRwkbGeometryType; +import org.geotools.feature.FeatureTypes; +import org.geotools.feature.simple.SimpleFeatureTypeBuilder; +import org.geotools.feature.type.BasicFeatureTypes; +import org.geotools.referencing.CRS; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.feature.type.AttributeDescriptor; +import org.opengis.feature.type.GeometryDescriptor; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryCollection; +import com.vividsolutions.jts.geom.LineString; +import com.vividsolutions.jts.geom.LinearRing; +import com.vividsolutions.jts.geom.MultiLineString; +import com.vividsolutions.jts.geom.MultiPoint; +import com.vividsolutions.jts.geom.MultiPolygon; +import com.vividsolutions.jts.geom.Point; +import com.vividsolutions.jts.geom.Polygon; + +/** + * Helper mapping between geotools and OGR feature types + * + * @author Andrea Aime - GeoSolutions + */ +class FeatureTypeMapper { + + /** + * Returns the geotools feature type equivalent from the native OGR one + * + * @param layer + * @param typeName + * @param namespaceURI + * @return + * @throws IOException + */ + SimpleFeatureType getFeatureType(Pointer layer, String typeName, String namespaceURI) + throws IOException { + Pointer definition = null; + try { + // setup the builder + SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder(); + tb.setName(typeName); + tb.setNamespaceURI(namespaceURI); + if (tb.getNamespaceURI() == null) { + tb.setNamespaceURI(BasicFeatureTypes.DEFAULT_NAMESPACE); + } + + // grab the layer definition + definition = OGR_L_GetLayerDefn(layer); + + // figure out the geometry + Class<? extends Geometry> geometryBinding = getGeometryBinding(definition); + if (geometryBinding != null) { + CoordinateReferenceSystem crs = getCRS(layer); + tb.add("the_geom", geometryBinding, crs); + } + + // get the non geometric fields + final int count = OGR_FD_GetFieldCount(definition); + for (int i = 0; i < count; i++) { + Pointer field = OGR_FD_GetFieldDefn(definition, i); + String name = OGR_Fld_GetNameRef(field).getCString(); + Class binding = getBinding(field); + int width = OGR_Fld_GetWidth(field); + if (width > 0) { + tb.length(width); + } + tb.add(name, binding); + } + + // compute a default parent feature type + if ((geometryBinding == Point.class) || (geometryBinding == MultiPoint.class)) { + tb.setSuperType(BasicFeatureTypes.POINT); + } else if ((geometryBinding == Polygon.class) + || (geometryBinding == MultiPolygon.class)) { + tb.setSuperType(BasicFeatureTypes.POLYGON); + } else if ((geometryBinding == LineString.class) + || (geometryBinding == MultiLineString.class)) { + tb.setSuperType(BasicFeatureTypes.LINE); + } + + return tb.buildFeatureType(); + } finally { + OGRUtils.releaseDefinition(definition); + } + } + + /** + * Maps the OGR field type to a java class + * + * @param field + * @return + */ + private Class getBinding(Pointer field) { + ValuedEnum<OGRFieldType> type = OGR_Fld_GetType(field); + int width = OGR_Fld_GetWidth(field); + long value = type.value(); + if (value == OGRFieldType.OFTInteger.value()) { + if (width <= 3) { + return Byte.class; + } else if (width <= 5) { + return Short.class; + } else if (width <= 9) { + return Integer.class; + } else if (width <= 19) { + return Long.class; + } else { + return BigDecimal.class; + } + } else if (value == OGRFieldType.OFTIntegerList.value()) { + return int[].class; + } else if (value == OGRFieldType.OFTReal.value()) { + if (width <= 12) { + return Float.class; + } else if (width <= 22) { + return Double.class; + } else { + return BigDecimal.class; + } + } else if (value == OGRFieldType.OFTRealList.value()) { + return double[].class; + } else if (value == OGRFieldType.OFTBinary.value()) { + return byte[].class; + } else if (value == OGRFieldType.OFTDate.value()) { + return java.sql.Date.class; + } else if (value == OGRFieldType.OFTTime.value()) { + return java.sql.Time.class; + } else if (value == OGRFieldType.OFTDateTime.value()) { + return java.sql.Timestamp.class; + } else { + // whatever else we'll map a string + return String.class; + } + } + + /** + * Returns a OGR field definition compatible with the specified attribute descriptor where: + * <ul> + * <li>width is the number of chars needed to format the strings equivalent of the number + * <li> + * <li>precision is the number of chars after decimal pont</li> + * <li>justification: right or left (in outputs)</li> + * </ul> + * + * @param ad + * @throws IOException + */ + public Pointer getOGRFieldDefinition(AttributeDescriptor ad) throws IOException { + final Class type = ad.getType().getBinding(); + final Pointer def; + Pointer<Byte> namePtr = pointerToCString(ad.getLocalName()); + if (Boolean.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTString); + OGR_Fld_SetWidth(def, 5); + } else if (Byte.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTInteger); + OGR_Fld_SetWidth(def, 3); + OGR_Fld_SetJustify(def, OGRJustification.OJRight); + } else if (Short.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTInteger); + OGR_Fld_SetWidth(def, 5); + OGR_Fld_SetJustify(def, OGRJustification.OJRight); + } else if (Integer.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTInteger); + OGR_Fld_SetWidth(def, 9); + OGR_Fld_SetJustify(def, OGRJustification.OJRight); + } else if (Long.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTInteger); + OGR_Fld_SetWidth(def, 19); + OGR_Fld_SetJustify(def, OGRJustification.OJRight); + } else if (BigInteger.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTInteger); + OGR_Fld_SetWidth(def, 32); + OGR_Fld_SetJustify(def, OGRJustification.OJRight); + } else if (BigDecimal.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTReal); + OGR_Fld_SetWidth(def, 32); + OGR_Fld_SetPrecision(def, 15); + OGR_Fld_SetJustify(def, OGRJustification.OJRight); + } else if (Float.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTReal); + OGR_Fld_SetWidth(def, 12); + OGR_Fld_SetPrecision(def, 7); + OGR_Fld_SetJustify(def, OGRJustification.OJRight); + } else if (Double.class.equals(type) || Number.class.isAssignableFrom(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTInteger); + OGR_Fld_SetWidth(def, 22); + OGR_Fld_SetPrecision(def, 16); + OGR_Fld_SetJustify(def, OGRJustification.OJRight); + } else if (String.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTString); + int length = FeatureTypes.getFieldLength(ad); + if (length <= 0) { + length = 255; + } + OGR_Fld_SetWidth(def, length); + } else if (byte[].class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTBinary); + } else if (java.sql.Date.class.isAssignableFrom(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTDate); + } else if (java.sql.Time.class.isAssignableFrom(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTTime); + } else if (java.util.Date.class.isAssignableFrom(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTDateTime); + } else { + throw new IOException("Cannot map " + type + " to an OGR type"); + } + + return def; + } + + /** + * Returns the OGR geometry type constant given a geometry attribute type + * + * @param descriptor + * @return + * @throws IOException + */ + public ValuedEnum<OGRwkbGeometryType> getOGRGeometryType(GeometryDescriptor descriptor) + throws IOException { + Class binding = descriptor.getType().getBinding(); + if (GeometryCollection.class.isAssignableFrom(binding)) { + if (MultiPoint.class.isAssignableFrom(binding)) { + return OGRwkbGeometryType.wkbMultiPoint; + } else if (MultiLineString.class.isAssignableFrom(binding)) { + return OGRwkbGeometryType.wkbMultiLineString; + } else if (MultiPolygon.class.isAssignableFrom(binding)) { + return OGRwkbGeometryType.wkbMultiPolygon; + } else { + return OGRwkbGeometryType.wkbGeometryCollection; + } + } else { + if (Point.class.isAssignableFrom(binding)) { + return OGRwkbGeometryType.wkbPoint; + } else if (LinearRing.class.isAssignableFrom(binding)) { + return OGRwkbGeometryType.wkbLinearRing; + } else if (LineString.class.isAssignableFrom(binding)) { + return OGRwkbGeometryType.wkbLineString; + } else if (Polygon.class.isAssignableFrom(binding)) { + return OGRwkbGeometryType.wkbPolygon; + } else { + return OGRwkbGeometryType.wkbUnknown; + } + } + } + + /** + * Returns the JTS geometry type equivalent to the layer native one + * + * @param definition + * @return + * @throws IOException + */ + private Class<? extends Geometry> getGeometryBinding(Pointer definition) throws IOException { + ValuedEnum<OGRwkbGeometryType> gt = OGR_FD_GetGeomType(definition); + long value = gt.value(); + // for line and polygon we return multi in any case since OGR will declare simple for + // multigeom + // anyways and then return simple or multi in the actual geoemtries depending on + // what it finds + if (value == OGRwkbGeometryType.wkbPoint.value() + || value == OGRwkbGeometryType.wkbPoint25D.value()) { + return Point.class; + } else if (value == OGRwkbGeometryType.wkbLinearRing.value()) { + return LinearRing.class; + } else if (value == OGRwkbGeometryType.wkbLineString.value() + || value == OGRwkbGeometryType.wkbLineString25D.value() + || value == OGRwkbGeometryType.wkbMultiLineString.value() + || value == OGRwkbGeometryType.wkbMultiLineString25D.value()) { + return MultiLineString.class; + } else if (value == OGRwkbGeometryType.wkbPolygon.value() + || value == OGRwkbGeometryType.wkbPolygon25D.value() + || value == OGRwkbGeometryType.wkbMultiPolygon.value() + || value == OGRwkbGeometryType.wkbMultiPolygon25D.value()) { + return MultiPolygon.class; + } else if (value == OGRwkbGeometryType.wkbGeometryCollection.value() + || value == OGRwkbGeometryType.wkbGeometryCollection25D.value()) { + return GeometryCollection.class; + } else if (value == OGRwkbGeometryType.wkbNone.value()) { + return null; + } else if (value == OGRwkbGeometryType.wkbUnknown.value()) { + return Geometry.class; + } else { + throw new IOException("Unknown geometry type: " + value); + } + } + + /** + * Returns the GeoTools {@link CoordinateReferenceSystem} equivalent to the layer native one + * + * @param layer + * @return + * @throws IOException + */ + private CoordinateReferenceSystem getCRS(Pointer layer) throws IOException { + Pointer spatialReference = null; + CoordinateReferenceSystem crs = null; + try { + spatialReference = OGR_L_GetSpatialRef(layer); + if (spatialReference == null) { + return null; + } + + try { + Pointer<Byte> code = OSRGetAuthorityCode(spatialReference, pointerToCString("EPSG")); + if (code != null) { + String fullCode = "EPSG:" + code; + crs = CRS.decode(fullCode); + } + } catch (Exception e) { + // fine, the code might be unknown to out authority + } + if (crs == null) { + try { + Pointer<Pointer<Byte>> wktPtr = allocatePointer(Byte.class); + OSRExportToWkt(spatialReference, wktPtr); + String wkt = wktPtr.getPointer(Byte.class).getCString(); + crs = CRS.parseWKT(wkt); + } catch (Exception e) { + // the wkt might reference an unsupported projection + } + } + return crs; + } finally { + OGRUtils.releaseSpatialReference(spatialReference); + } + } + + /** + * Returns a Pointer to a OGR spatial reference object equivalent to the specified GeoTools CRS + * + * @param crs + * @return + */ + public Pointer getSpatialReference(CoordinateReferenceSystem crs) { + if (crs == null) { + return null; + } + + // use tostring to get a lenient wkt translation + String wkt = crs.toString(); + return OSRNewSpatialReference(pointerToCString(wkt)); + } + +} Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FilterToRestrictedWhere.java =================================================================== --- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FilterToRestrictedWhere.java (rev 0) +++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FilterToRestrictedWhere.java 2012-01-15 18:25:20 UTC (rev 38482) @@ -0,0 +1,429 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package org.geotools.data.ogr; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.Iterator; + +import org.geotools.factory.Hints; +import org.geotools.util.ConverterFactory; +import org.geotools.util.Converters; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.feature.type.AttributeDescriptor; +import org.opengis.filter.And; +import org.opengis.filter.BinaryComparisonOperator; +import org.opengis.filter.BinaryLogicOperator; +import org.opengis.filter.ExcludeFilter; +import org.opengis.filter.Filter; +import org.opengis.filter.FilterVisitor; +import org.opengis.filter.Id; +import org.opengis.filter.IncludeFilter; +import org.opengis.filter.Not; +import org.opengis.filter.Or; +import org.opengis.filter.PropertyIsBetween; +import org.opengis.filter.PropertyIsEqualTo; +import org.opengis.filter.PropertyIsGreaterThan; +import org.opengis.filter.PropertyIsGreaterThanOrEqualTo; +import org.opengis.filter.PropertyIsLessThan; +import org.opengis.filter.PropertyIsLessThanOrEqualTo; +import org.opengis.filter.PropertyIsLike; +import org.opengis.filter.PropertyIsNotEqualTo; +import org.opengis.filter.PropertyIsNull; +import org.opengis.filter.expression.Add; +import org.opengis.filter.expression.Divide; +import org.opengis.filter.expression.Expression; +import org.opengis.filter.expression.ExpressionVisitor; +import org.opengis.filter.expression.Function; +import org.opengis.filter.expression.Literal; +import org.opengis.filter.expression.Multiply; +import org.opengis.filter.expression.NilExpression; +import org.opengis.filter.expression.PropertyName; +import org.opengis.filter.expression.Subtract; +import org.opengis.filter.spatial.BBOX; +import org.opengis.filter.spatial.Beyond; +import org.opengis.filter.spatial.Contains; +import org.opengis.filter.spatial.Crosses; +import org.opengis.filter.spatial.DWithin; +import org.opengis.filter.spatial.Disjoint; +import org.opengis.filter.spatial.Equals; +import org.opengis.filter.spatial.Intersects; +import org.opengis.filter.spatial.Overlaps; +import org.opengis.filter.spatial.Touches; +import org.opengis.filter.spatial.Within; + +/** + * Encodes a compliant filter to the "restricted where" syntax supported by OGR: + * + * <pre> + * @condition@ = @field_name@ @binary_operator@ @value@ | "(" @condition@ ")" @binary_logical_operator@ + * "(" @condition@ ")" + * @binary_operator@ = "<" | ">" | "<=" | ">=" | "<>" | "=" + * @binary_logical_operator@ = "AND" | "OR" + * @field_name@ = @string_token@ + * @value@ = @string_token@ | @numeric_value@ | @string_value@ + * @string_value@ = "'" @characters@ "'" + * </pre> + * + * Implementation wise this is a widely cut down version of JDBC's module FilterToSQL + * + * @author Andrea Aime - GeoSolutions + */ +class FilterToRestrictedWhere implements FilterVisitor, ExpressionVisitor { + /** error message for exceptions */ + protected static final String IO_ERROR = "io problem writing filter"; + + /** the schema the encoder will be used to be encode sql for */ + protected SimpleFeatureType featureType; + + StringWriter out = new StringWriter(); + + public FilterToRestrictedWhere(SimpleFeatureType featureType) { + this.featureType = featureType; + } + + public String getRestrictedWhere() { + return out.toString(); + } + + /** + * Writes the SQL for the PropertyIsBetween Filter. + * + * @param filter the Filter to be visited. + * + * @throws RuntimeException for io exception with writer + */ + public Object visit(PropertyIsBetween filter, Object extraData) throws RuntimeException { + Expression expr = (Expression) filter.getExpression(); + Expression lowerbounds = (Expression) filter.getLowerBoundary(); + Expression upperbounds = (Expression) filter.getUpperBoundary(); + + Class context; + AttributeDescriptor attType = (AttributeDescriptor) expr.evaluate(featureType); + if (attType != null) { + context = attType.getType().getBinding(); + } else { + context = String.class; + } + + out.write("(("); + expr.accept(this, extraData); + out.write(">="); + lowerbounds.accept(this, context); + out.write(") AND ("); + expr.accept(this, extraData); + out.write("<="); + upperbounds.accept(this, context); + out.write("))"); + + return extraData; + } + + /** + * Write the SQL for an And filter + * + * @param filter the filter to visit + * @param extraData extra data (unused by this method) + * + */ + public Object visit(And filter, Object extraData) { + return visit((BinaryLogicOperator) filter, "AND"); + } + + /** + * Write the SQL for an Or filter + * + * @param filter the filter to visit + * @param extraData extra data (unused by this method) + * + */ + public Object visit(Or filter, Object extraData) { + return visit((BinaryLogicOperator) filter, "OR"); + } + + /** + * Common implementation for BinaryLogicOperator filters. This way they're all handled + * centrally. + * + * @param filter the logic statement to be turned into SQL. + * @param extraData extra filter data. Not modified directly by this method. + */ + protected Object visit(BinaryLogicOperator filter, Object extraData) { + String type = (String) extraData; + out.write("("); + + Iterator<Filter> list = filter.getChildren().iterator(); + while (list.hasNext()) { + list.next().accept(this, extraData); + + if (list.hasNext()) { + out.write(" " + type + " "); + } + } + out.write(")"); + return extraData; + } + + public Object visit(PropertyIsEqualTo filter, Object extraData) { + visitBinaryComparisonOperator((BinaryComparisonOperator) filter, "="); + return extraData; + } + + public Object visit(PropertyIsGreaterThanOrEqualTo filter, Object extraData) { + visitBinaryComparisonOperator((BinaryComparisonOperator) filter, ">="); + return extraData; + } + + public Object visit(PropertyIsGreaterThan filter, Object extraData) { + visitBinaryComparisonOperator((BinaryComparisonOperator) filter, ">"); + return extraData; + } + + public Object visit(PropertyIsLessThan filter, Object extraData) { + visitBinaryComparisonOperator((BinaryComparisonOperator) filter, "<"); + return extraData; + } + + public Object visit(PropertyIsLessThanOrEqualTo filter, Object extraData) { + visitBinaryComparisonOperator((BinaryComparisonOperator) filter, "<="); + return extraData; + } + + public Object visit(PropertyIsNotEqualTo filter, Object extraData) { + visitBinaryComparisonOperator((BinaryComparisonOperator) filter, "!="); + return extraData; + } + + protected void visitBinaryComparisonOperator(BinaryComparisonOperator filter, Object extraData) + throws RuntimeException { + Expression left = filter.getExpression1(); + Expression right = filter.getExpression2(); + + // see if we can get some indication on how to evaluate literals + Class leftContext = null, rightContext = null; + if (left instanceof PropertyName) { + AttributeDescriptor attType = (AttributeDescriptor) left.evaluate(featureType); + if (attType != null) { + rightContext = attType.getType().getBinding(); + } + } + if (rightContext == null && right instanceof PropertyName) { + AttributeDescriptor attType = (AttributeDescriptor) right.evaluate(featureType); + if (attType != null) { + leftContext = attType.getType().getBinding(); + } + } + + String type = (String) extraData; + left.accept(this, leftContext); + out.write(" " + type + " "); + right.accept(this, rightContext); + } + + public Object visit(PropertyName expression, Object extraData) throws RuntimeException { + AttributeDescriptor attribute = null; + try { + attribute = (AttributeDescriptor) expression.evaluate(featureType); + } catch (Exception e) { + // just log and fall back on just encoding propertyName straight up + String msg = "Error occured mapping " + expression + " to feature type"; + } + String name = null; + if (attribute != null) { + name = attribute.getLocalName(); + } else { + name = expression.getPropertyName(); + } + out.write(name); + + return extraData; + } + + /** + * Export the contents of a Literal Expresion + * + * @param expression the Literal to export + * + * @throws RuntimeException for io exception with writer + */ + public Object visit(Literal expression, Object context) throws RuntimeException { + // type to convert the literal to + Class target = null; + if (context instanceof Class) { + target = (Class) context; + } + + // evaluate the expression + Object literal = evaluateLiteral(expression, target); + writeLiteral(literal); + return context; + } + + protected Object evaluateLiteral(Literal expression, Class target) { + Object literal = null; + + // HACK: let expression figure out the right value for numbers, + // since the context is almost always improperly set and the + // numeric converters try to force floating points to integrals + // JD: the above is no longer true, so instead do a safe conversion + if (target != null) { + // use the target type + if (Number.class.isAssignableFrom(target)) { + literal = Converters.convert(expression.evaluate(null), target, new Hints( + ConverterFactory.SAFE_CONVERSION, true)); + } else { + literal = expression.evaluate(null, target); + } + } + // if the target was not known, of the conversion failed, try the + // type guessing dance literal expression does only for the following + // method call + if (literal == null) + literal = expression.evaluate(null); + + // if that failed as well, grab the value as is + if (literal == null) + literal = expression.getValue(); + + return literal; + } + + /** + * Writes out a non null, non geometry literal. The base class properly handles null, numeric + * and booleans (true|false), and turns everything else into a string. Subclasses are expected + * to override this shall they need a different treatment (e.g. for dates) + * + * @param literal + * @throws IOException + */ + protected void writeLiteral(Object literal) { + if (literal == null) { + out.write("NULL"); + } else if (literal instanceof Number || literal instanceof Boolean) { + out.write(String.valueOf(literal)); + } else { + // we don't know what this is, let's convert back to a string + String encoding = (String) Converters.convert(literal, String.class, null); + if (encoding == null) { + // could not convert back to string, use original l value + encoding = literal.toString(); + } + + // sigle quotes must be escaped to have a valid sql string + String escaped = encoding.replaceAll("'", "''"); + out.write("'" + escaped + "'"); + } + } + + public Object visit(NilExpression expression, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Add expression, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Divide expression, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Function expression, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Multiply expression, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Subtract expression, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visitNullFilter(Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(ExcludeFilter filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(IncludeFilter filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Id filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Not filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(PropertyIsLike filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(PropertyIsNull filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(BBOX filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Beyond filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Contains filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Crosses filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Disjoint filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(DWithin filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Equals filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Intersects filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Overlaps filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Touches filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Within filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + + } Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/GdalInit.java =================================================================== --- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/GdalInit.java (rev 0) +++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/GdalInit.java 2012-01-15 18:25:20 UTC (rev 38482) @@ -0,0 +1,96 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2007-2008, Open Source Geospatial Foundation (OSGeo) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package org.geotools.data.ogr; + +import org.bridj.BridJ; +import org.geotools.data.ogr.bridj.OgrLibrary; + +/** + * Helper class allowing to locate the GDAL library and attach to it + * + * @source $URL: https://svn.osgeo.org/geotools/trunk/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/GdalInit.java $ + */ +class GdalInit { + + private static volatile String NATIVE_NAME; + + public static void init() { + if (NATIVE_NAME == null) { + synchronized (GdalInit.class) { + if (NATIVE_NAME == null) { + NATIVE_NAME = System.getProperty("GDAL_LIBRARY_NAME"); + if(NATIVE_NAME != null) { + // someone told us its name + if(!checkNativeName(NATIVE_NAME)) { + throw new RuntimeException( + "Failed to bind to user specified gdal library named: " + NATIVE_NAME); + } + } else { + // on linux platforms libgdal is normally associated with its version, + // painful... + // generate a bunch of the known release numbers, plus more for the future + // :) + if (!checkNativeName("gdal") && !(checkNativeName("gdal_fw"))) { + int x = 1; + // for (int x = 2; x >= 1; x--) { + for (int y = 10; y >= 0; y--) { + if (checkNativeName("gdal" + x + "." + y)) { + return; + } + for (int z = 5; z >= 0; z--) { + if (checkNativeName("gdal" + x + "." + y + "." + z)) { + return; + } + } + } + // } + throw new RuntimeException( + "Failed to automatically guess the gdal library name, please set the GDAL_LIBRARY_NAME system variable"); + } + } + } + } + } + } + + static boolean checkNativeName(String name) { + try { + if (BridJ.getNativeLibrary(name) != null) { + registerAlias(name); + OgrLibrary.OGRGetDriverCount(); + + NATIVE_NAME = name; + + return true; + } else { + return false; + } + } catch (Throwable t) { + return false; + } + } + + private static void registerAlias(String name) { + System.out.println("Registered library as " + name); + BridJ.addNativeLibraryAlias("ogr", name); + BridJ.addNativeLibraryAlias("osr", name); + BridJ.addNativeLibraryAlias("cplError", name); + BridJ.addNativeLibraryAlias("gdal", name); + } + + +} Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFeatureStore.java =================================================================== --- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFeatureStore.java (rev 0) +++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFeatureStore.java 2012-01-15 18:25:20 UTC (rev 38482) @@ -0,0 +1,166 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2007-2008, Open Source Geospatial Foundation (OSGeo) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package org.geotools.data.ogr; + +import java.io.IOException; + +import org.bridj.Pointer; +import org.geotools.data.FeatureReader; +import org.geotools.data.FeatureWriter; +import org.geotools.data.Query; +import org.geotools.data.QueryCapabilities; +import org.geotools.data.ResourceInfo; +import org.geotools.data.Transaction; +import org.geotools.data.store.ContentEntry; +import org.geotools.data.store.ContentFeatureStore; +import org.geotools.data.store.ContentState; +import org.geotools.geometry.jts.ReferencedEnvelope; +import org.opengis.feature.FeatureVisitor; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.feature.type.Name; + +import com.vividsolutions.jts.geom.GeometryFactory; + +/** + * FeatureStore for the OGR store, based on the {@link ContentFeatureStore} framework + * + * @author Andrea Aime - GeoSolutions + */ +@SuppressWarnings("rawtypes") +class OGRFeatureStore extends ContentFeatureStore { + + OGRFeatureSource delegate; + + public OGRFeatureStore(ContentEntry entry, Query query) { + super(entry, query); + delegate = new OGRFeatureSource(entry, query); + } + + @Override + protected FeatureWriter<SimpleFeatureType, SimpleFeature> getWriterInternal(Query query, + int flags) throws IOException { + Pointer dataSource = null; + Pointer layer = null; + boolean cleanup = true; + try { + // grab the layer + String typeName = getEntry().getTypeName(); + dataSource = getDataStore().openOGRDataSource(true); + layer = getDataStore().openOGRLayer(dataSource, typeName); + + FeatureReader<SimpleFeatureType, SimpleFeature> reader = delegate.getReaderInternal( + dataSource, layer, query); + GeometryFactory gf = delegate.getGeometryFactory(query); + OGRDirectFeatureWriter result = new OGRDirectFeatureWriter(dataSource, layer, reader, + getSchema(), gf); + cleanup = false; + return result; + } finally { + if (cleanup) { + OGRUtils.releaseLayer(layer); + OGRUtils.releaseDataSource(dataSource); + } + } + } + + // ---------------------------------------------------------------------------------------- + // METHODS DELEGATED TO OGRFeatureSource + // ---------------------------------------------------------------------------------------- + + public OGRDataStore getDataStore() { + return delegate.getDataStore(); + } + + public Transaction getTransaction() { + return delegate.getTransaction(); + } + + public ResourceInfo getInfo() { + return delegate.getInfo(); + } + + public QueryCapabilities getQueryCapabilities() { + return delegate.getQueryCapabilities(); + } + + @Override + protected ReferencedEnvelope getBoundsInternal(Query query) throws IOException { + return delegate.getBoundsInternal(query); + } + + @Override + protected int getCountInternal(Query query) throws IOException { + return delegate.getCountInternal(query); + } + + @Override + protected FeatureReader<SimpleFeatureType, SimpleFeature> getReaderInternal(Query query) + throws IOException { + return delegate.getReaderInternal(query); + } + + @Override + protected SimpleFeatureType buildFeatureType() throws IOException { + return delegate.buildFeatureType(); + } + + @Override + public ContentEntry getEntry() { + return delegate.getEntry(); + } + + @Override + public Name getName() { + return delegate.getName(); + } + + @Override + public ContentState getState() { + return delegate.getState(); + } + + @Override + public void setTransaction(Transaction transaction) { + super.setTransaction(transaction); + + if (delegate.getTransaction() != transaction) { + delegate.setTransaction(transaction); + } + } + + @Override + protected boolean canFilter() { + return delegate.canFilter(); + } + + @Override + protected boolean canSort() { + return delegate.canSort(); + } + + @Override + protected boolean canRetype() { + return delegate.canRetype(); + } + + @Override + protected boolean handleVisitor(Query query, FeatureVisitor visitor) throws IOException { + return delegate.handleVisitor(query, visitor); + } + +} Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFilterTranslator.java =================================================================== --- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFilterTranslator.java (rev 0) +++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFilterTranslator.java 2012-01-15 18:25:20 UTC (rev 38482) @@ -0,0 +1,214 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2007-2008, Open Source Geospatial Foundation (OSGeo) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package org.geotools.data.ogr; + +import org.geotools.filter.FilterCapabilities; +import org.geotools.filter.visitor.PostPreProcessFilterSplittingVisitor; +import org.geotools.filter.visitor.SimplifyingFilterVisitor; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.filter.And; +import org.opengis.filter.Filter; +import org.opengis.filter.Or; +import org.opengis.filter.PropertyIsBetween; +import org.opengis.filter.PropertyIsEqualTo; +import org.opengis.filter.PropertyIsGreaterThan; +import org.opengis.filter.PropertyIsGreaterThanOrEqualTo; +import org.opengis.filter.PropertyIsLessThan; +import org.opengis.filter.PropertyIsLessThanOrEqualTo; +import org.opengis.filter.PropertyIsNotEqualTo; +import org.opengis.filter.expression.Expression; +import org.opengis.filter.expression.Literal; +import org.opengis.filter.expression.PropertyName; +import org.opengis.filter.spatial.BBOX; +import org.opengis.filter.spatial.BinarySpatialOperator; +import org.opengis.filter.spatial.Contains; +import org.opengis.filter.spatial.Crosses; +import org.opengis.filter.spatial.Equals; +import org.opengis.filter.spatial.Intersects; +import org.opengis.filter.spatial.Overlaps; +import org.opengis.filter.spatial.Touches; +import org.opengis.filter.spatial.Within; + +import com.vividsolutions.jts.geom.Geometry; + +/** + * Helper which translates the GeoTools filters into the filter bits that OGR understands + * + * @author Andrea Aime - GeoSolutions + */ +class OGRFilterTranslator { + + static final FilterCapabilities ATTRIBUTE_FILTER_CAPABILITIES; + + static final FilterCapabilities GEOMETRY_FILTER_CAPABILITIES; + + static final FilterCapabilities STRICT_GEOMETRY_FILTER_CAPABILITIES; + + static final FilterCapabilities EXTENDED_FILTER_CAPABILITIES; + + static { + // attribute filters, these we can encode fully + ATTRIBUTE_FILTER_CAPABILITIES = new FilterCapabilities(); + ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsBetween.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsEqualTo.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsNotEqualTo.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsGreaterThan.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsLessThan.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsGreaterThanOrEqualTo.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsLessThanOrEqualTo.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsLessThanOrEqualTo.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(Or.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(And.class); + + // we cannot encode these full, but have the capabilities extract + // any filter that can use geometric intersection as its base (bbox is the only + // one that we're sure to get support for) + GEOMETRY_FILTER_CAPABILITIES = new FilterCapabilities(); + GEOMETRY_FILTER_CAPABILITIES.addType(BBOX.class); + GEOMETRY_FILTER_CAPABILITIES.addType(Contains.class); + GEOMETRY_FILTER_CAPABILITIES.addType(Crosses.class); + GEOMETRY_FILTER_CAPABILITIES.addType(Equals.class); + GEOMETRY_FILTER_CAPABILITIES.addType(Intersects.class); + GEOMETRY_FILTER_CAPABILITIES.addType(Overlaps.class); + GEOMETRY_FILTER_CAPABILITIES.addType(Touches.class); + GEOMETRY_FILTER_CAPABILITIES.addType(Within.class); + + // the geometry filters we can encode 1-1 + STRICT_GEOMETRY_FILTER_CAPABILITIES = new FilterCapabilities(); + STRICT_GEOMETRY_FILTER_CAPABILITIES.addType(BBOX.class); + + // the extended caps, which work only assuming there is at most a single bbox filter + // in the filter to be encoded + EXTENDED_FILTER_CAPABILITIES = new FilterCapabilities(); + EXTENDED_FILTER_CAPABILITIES.addAll(ATTRIBUTE_FILTER_CAPABILITIES); + EXTENDED_FILTER_CAPABILITIES.addAll(STRICT_GEOMETRY_FILTER_CAPABILITIES); + } + + private SimpleFeatureType schema; + + private Filter filter; + + public OGRFilterTranslator(SimpleFeatureType schema, Filter filter) { + this.schema = schema; + SimplifyingFilterVisitor simplifier = new SimplifyingFilterVisitor(); + this.filter = (Filter) filter.accept(simplifier, null); + } + + /** + * Returns true if this filter can be fully encoded without requiring further post processing + * + * @return + */ + public boolean isFilterFullySupported() { + if (filter == Filter.INCLUDE || filter == Filter.EXCLUDE) { + return true; + } + + // we can encode fully an attribute filter plus a bbox spatial filter + PostPreProcessFilterSplittingVisitor visitor = new PostPreProcessFilterSplittingVisitor( + ATTRIBUTE_FILTER_CAPABILITIES, schema, null); + filter.accept(visitor, null); + Filter postFilter = visitor.getFilterPost(); + return postFilter == Filter.INCLUDE || postFilter instanceof BBOX; + } + + /** + * Returns the post filter that could not be encoded + * + * @return + */ + public Filter getPostFilter() { + // see if the query has a single bbox filter (that's how much we're sure to be able to + // encode) + PostPreProcessFilterSplittingVisitor visitor = new PostPreProcessFilterSplittingVisitor( + STRICT_GEOMETRY_FILTER_CAPABILITIES, schema, null); + filter.accept(visitor, null); + Filter preFilter = visitor.getFilterPre(); + + if (preFilter == null || preFilter instanceof BBOX) { + // ok, then we can extract using the extended caps + visitor = new PostPreProcessFilterSplittingVisitor(EXTENDED_FILTER_CAPABILITIES, + schema, null); + filter.accept(visitor, null); + return visitor.getFilterPost(); + } else { + // though luck, there is more than a single bbox filter + visitor = new PostPreProcessFilterSplittingVisitor(ATTRIBUTE_FILTER_CAPABILITIES, + schema, null); + filter.accept(visitor, null); + return visitor.getFilterPost(); + } + } + + /** + * Parses the Geotools filter and tries to extract an intersecting geometry that can be used as + * the OGR spatial filter + * + * @param schema + * @param filter + * @return + */ + public Geometry getSpatialFilter() { + // TODO: switch to the non deprecated splitter (that no one seems to be using) + PostPreProcessFilterSplittingVisitor visitor = new PostPreProcessFilterSplittingVisitor( + GEOMETRY_FILTER_CAPABILITIES, schema, null); + filter.accept(visitor, null); + Filter preFilter = visitor.getFilterPre(); + if (preFilter instanceof BinarySpatialOperator) { + BinarySpatialOperator bso = ((BinarySpatialOperator) preFilter); + Expression geomExpression = null; + if (bso.getExpression1() instanceof PropertyName + && bso.getExpression2() instanceof Literal) { + geomExpression = bso.getExpression2(); + } else if (bso.getExpression1() instanceof Literal + && bso.getExpression2() instanceof PropertyName) { + geomExpression = bso.getExpression1(); + } + if (geomExpression != null) { + Geometry geom = geomExpression.evaluate(null, Geometry.class); + return geom; + } + } + return null; + } + + /** + * Parses the GeoTools filter and tries to extract an SQL expression that can be used as the OGR + * attribute filter + * + * @param schema + * @param filter + * @return + */ + public String getAttributeFilter() { + // TODO: switch to the non deprecated splitter (that no one seems to be using) + PostPreProcessFilterSplittingVisitor visitor = new PostPreProcessFilterSplittingVisitor( + ATTRIBUTE_FILTER_CAPABILITIES, schema, null); + filter.accept(visitor, null); + Filter preFilter = visitor.getFilterPre(); + if (preFilter != Filter.EXCLUDE && preFilter != Filter.INCLUDE) { + FilterToRestrictedWhere sqlConverter = new FilterToRestrictedWhere(schema); + preFilter.accept(sqlConverter, null); + return sqlConverter.getRestrictedWhere(); + } + return null; + } + + public Filter getFilter() { + return filter; + } +} Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRUtils.java =================================================================== --- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRUtils.java (rev 0) +++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRUtils.java 2012-01-15 18:25:20 UTC (rev 38482) @@ -0,0 +1,129 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2007-2008, Open Source Geospatial Foundation (OSGeo) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package org.geotools.data.ogr; + +import static org.geotools.data.ogr.bridj.OgrLibrary.*; +import static org.geotools.data.ogr.bridj.CplErrorLibrary.*; + +import java.io.IOException; + +import org.bridj.Pointer; + +/** + * Common utilities to deal with OGR pointers + * + * @author Andrea Aime - GeoSolutions + */ +@SuppressWarnings("rawtypes") +class OGRUtils { + + private static boolean HAS_L_GETNAME; + + public static void releaseDataSource(Pointer dataSet) { + if (dataSet != null) { + OGRReleaseDataSource(dataSet); + dataSet.release(); + } + } + + public static void releaseLayer(Pointer layer) { + if (layer != null) { + // OGR_L_Dereference(layer); + layer.release(); + } + + } + + public static void releaseDefinition(Pointer definition) { + if (definition != null) { + // OGR_FD_Destroy(definition); + definition.release(); + } + } + + public static void releaseSpatialReference(Pointer spatialReference) { + if (spatialReference != null) { + // OSRDestroySpatialReference(spatialReference); + spatialReference.release(); + } + } + + public static String getCString(Pointer<Byte> ptr) { + if(ptr == null) { + return null; + } else { + return ptr.getCString(); + } + } + + /** + * Gets a layer name in a version independent way + * @param layer + */ + public static String getLayerName(Pointer layer) { + Pointer<Byte> namePtr = null; + try { + // this one is more efficient but has been added recently + if(HAS_L_GETNAME) { + namePtr = OGR_L_GetName(layer); + } + } catch(Exception e) { + HAS_L_GETNAME = false; + } + if(namePtr == null) { + Pointer layerDefinition = OGR_L_GetLayerDefn(layer); + namePtr = OGR_FD_GetName(layerDefinition); + } + return getCString(namePtr); + } + + /** + * Checks the OGRErr status code and throws java exceptions accordingly + * + * @param ogrError + * @throws IOException + */ + public static void checkError(int ogrError) throws IOException { + if (ogrError == OGRERR_NONE) { + return; + } + + String error = getCString(CPLGetLastErrorMsg()); + + switch (ogrError) { + case OGRERR_CORRUPT_DATA: + throw new IOException("OGR reported a currupt data error: " + error); + case OGRERR_FAILURE: + throw new IOException("OGR reported a generic failure: " + error); + case OGRERR_INVALID_HANDLE: + throw new IOException("OGR reported an invalid handle error: " + error); + case OGRERR_NOT_ENOUGH_DATA: + throw new IOException("OGR reported not enough data was provided in the last call: " + error); + case OGRERR_NOT_ENOUGH_MEMORY: + throw new IOException("OGR reported not enough memory is available: " + error); + case OGRERR_UNSUPPORTED_GEOMETRY_TYPE: + throw new IOException("OGR reported a unsupported geometry type error: " + error); + case OGRERR_UNSUPPORTED_OPERATION: + throw new IOException("OGR reported a unsupported operation error: " + error); + case OGRERR_UNSUPPORTED_SRS: + throw new IOException("OGR reported a unsupported SRS error: " + error); + default: + throw new IOException("OGR reported an unrecognized error code: " + ogrError); + } + } + +} Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/BridjUtilities.java =================================================================== --- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/BridjUtilities.java (rev 0) +++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/BridjUtilities.java 2012-01-15 18:25:20 UTC (rev 38482) @@ -0,0 +1,19 @@ +package org.geotools.data.ogr.bridj; + +import org.bridj.Pointer; + +/** + * + * + * @source $URL: https://svn.osgeo.org/geotools/trunk/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/BridjUtilities.java $ + */ +public class BridjUtilities { + + public static String getCString(Pointer<?> ptr) { + if (ptr == null) { + return null; + } else { + return ptr.getCString(); + } + } +} Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/CplErrorLibrary.java =================================================================== --- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/CplErrorLibrary.java (rev 0) +++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/CplErrorLibrary.java 2012-01-15 18:25:20 UTC (rev 38482) @@ -0,0 +1,82 @@ +package org.geotools.data.ogr.bridj; +import java.util.Collections; +import java.util.Iterator; +import org.bridj.BridJ; +import org.bridj.CRuntime; +import org.bridj.FlagSet; +import org.bridj.IntValuedEnum; +import org.bridj.Pointer; +import org.bridj.ValuedEnum; +import org.bridj.ann.Library; +import org.bridj.ann.Runtime; +import org.geotools.data.ogr.bridj.OsrLibrary.CPLErrorHandler; +/** + * Wrapper for library <b>cplError</b><br> + * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br> + * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br> + * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> or <a href="http://bridj.googlecode.com/">BridJ</a> . + */ +@Library("cplError") +@Runtime(CRuntime.class) +public class CplErrorLibrary { + static { + BridJ.register(); + } + public enum CPLErr implements IntValuedEnum<CPLErr > { + CE_None(0), + CE_Debug(1), + CE_Warning(2), + CE_Failure(3), + CE_Fatal(4); + CPLErr(long value) { + this.value = value; + } + public final long value; + public long value() { + return this.value; + } + public Iterator<CPLErr > iterator() { + return Collections.singleton(this).iterator(); + } + public static ValuedEnum<CPLErr > fromValue(long value) { + return FlagSet.fromValue(value, values()); + } + }; + /// <i>native declaration : /home/aaime/devel/gdal/gdal-1.8.0/port/cpl_error.h</i> + public static final int CPLE_UserInterrupt = (int)9; + /// <i>native declaration : /home/aaime/devel/gdal/gdal-1.8.0/port/cpl_... [truncated message content] |
|
From: <svn...@os...> - 2012-01-15 18:21:36
|
Author: aaime
Date: 2012-01-15 10:21:29 -0800 (Sun, 15 Jan 2012)
New Revision: 38481
Modified:
branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/FilterDOMParser.java
branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/GeometryFilterImpl.java
branches/2.7.x/modules/library/main/src/test/java/org/geotools/filter/DOMParserTest.java
Log:
[GEOT-4004] FilterDomParser handles Crosses as Touches (patch by Jan De Moerloose)
Modified: branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/FilterDOMParser.java
===================================================================
--- branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/FilterDOMParser.java 2012-01-15 17:55:59 UTC (rev 38480)
+++ branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/FilterDOMParser.java 2012-01-15 18:21:29 UTC (rev 38481)
@@ -435,7 +435,7 @@
return FILTER_FACT.touches( left, right );
case FilterType.GEOMETRY_CROSSES:
- return FILTER_FACT.touches( left, right );
+ return FILTER_FACT.crosses( left, right );
case FilterType.GEOMETRY_WITHIN:
return FILTER_FACT.within( left, right );
Modified: branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/GeometryFilterImpl.java
===================================================================
--- branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/GeometryFilterImpl.java 2012-01-15 17:55:59 UTC (rev 38480)
+++ branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/GeometryFilterImpl.java 2012-01-15 18:21:29 UTC (rev 38481)
@@ -263,6 +263,8 @@
operator = " disjoint ";
} else if (filterType == GEOMETRY_INTERSECTS) {
operator = " intersects ";
+ } else if (filterType == GEOMETRY_TOUCHES) {
+ operator = " touches ";
} else if (filterType == GEOMETRY_CROSSES) {
operator = " crosses ";
} else if (filterType == GEOMETRY_WITHIN) {
Modified: branches/2.7.x/modules/library/main/src/test/java/org/geotools/filter/DOMParserTest.java
===================================================================
--- branches/2.7.x/modules/library/main/src/test/java/org/geotools/filter/DOMParserTest.java 2012-01-15 17:55:59 UTC (rev 38480)
+++ branches/2.7.x/modules/library/main/src/test/java/org/geotools/filter/DOMParserTest.java 2012-01-15 18:21:29 UTC (rev 38481)
@@ -35,6 +35,7 @@
import org.opengis.filter.expression.Literal;
import org.opengis.filter.expression.PropertyName;
import org.opengis.filter.spatial.Beyond;
+import org.opengis.filter.spatial.Crosses;
import org.opengis.filter.spatial.DWithin;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -43,6 +44,7 @@
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.Point;
/**
@@ -236,6 +238,15 @@
LOGGER.fine("parsed filter is " + test);
}
+ public void testCrosses() throws Exception {
+ Filter test = parseDocument("crosses.xml");
+ assertTrue(test instanceof Crosses);
+ Crosses cr = (Crosses) test;
+ assertEquals("the_geom", ((PropertyName) cr.getExpression1()).getPropertyName());
+ assertTrue(((Literal) cr.getExpression2()).getValue() instanceof LineString);
+ LOGGER.fine("parsed filter is " + test);
+ }
+
public void test28() throws Exception {
FidFilter filter = (FidFilter) parseDocumentFirst("test28.xml");
String[] fids = filter.getFids();
|
|
From: <svn...@os...> - 2012-01-15 17:56:09
|
Author: aaime
Date: 2012-01-15 09:55:59 -0800 (Sun, 15 Jan 2012)
New Revision: 38480
Modified:
branches/2.7.x/modules/unsupported/ogr/pom.xml
branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FeatureMapper.java
branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/GeometryMapper.java
branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRDataStore.java
branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRDataStoreFactory.java
branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRDirectFeatureWriter.java
branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFeatureReader.java
branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFeatureSource.java
branches/2.7.x/modules/unsupported/ogr/src/test/java/org/geotools/data/ogr/OGRDataStoreTest.java
Log:
[GEOT-3982] ogr - backport from trunk to branch 2.7.x in order to support createSchema(SimpleFeatureCollection, ...)
Modified: branches/2.7.x/modules/unsupported/ogr/pom.xml
===================================================================
--- branches/2.7.x/modules/unsupported/ogr/pom.xml 2012-01-12 07:30:49 UTC (rev 38479)
+++ branches/2.7.x/modules/unsupported/ogr/pom.xml 2012-01-15 17:55:59 UTC (rev 38480)
@@ -15,7 +15,7 @@
<parent>
<groupId>org.geotools</groupId>
- <artifactId>plugin</artifactId>
+ <artifactId>unsupported</artifactId>
<version>2.7-SNAPSHOT</version>
</parent>
@@ -48,6 +48,13 @@
</license>
</licenses>
+ <repositories>
+ <repository>
+ <id>nativelibs4java-repo</id>
+ <name>NativeLibs4Java Maven Repository</name>
+ <url>http://nativelibs4java.sourceforge.net/maven</url>
+ </repository>
+ </repositories>
<!-- =========================================================== -->
<!-- Developers and Contributors -->
@@ -72,9 +79,24 @@
<dependencies>
<dependency>
<groupId>org.geotools</groupId>
- <artifactId>gt-main</artifactId>
+ <artifactId>gt-data</artifactId>
<version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.nativelibs4java</groupId>
+ <artifactId>bridj</artifactId>
+ <classifier>c-only</classifier>
+ <version>0.6</version>
+
+ <exclusions>
+ <exclusion>
+ <groupId>com.nativelibs4java.thirdparty.com.google.android</groupId>
+ <artifactId>dx</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
+
<!-- Test dependencies -->
<dependency>
@@ -95,6 +117,30 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
+
+ <dependency>
+ <groupId>org.geotools</groupId>
+ <artifactId>gt-jdbc</artifactId>
+ <version>2.7-SNAPSHOT</version>
+ </dependency>
</dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <systemProperties>
+ <property>
+ <name>java.library.path</name>
+ <value>${java.library.path}</value>
+ </property>
+ </systemProperties>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
</project>
Modified: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FeatureMapper.java
===================================================================
--- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FeatureMapper.java 2012-01-12 07:30:49 UTC (rev 38479)
+++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FeatureMapper.java 2012-01-15 17:55:59 UTC (rev 38480)
@@ -16,15 +16,27 @@
*/
package org.geotools.data.ogr;
+import static org.bridj.Pointer.*;
+import static org.geotools.data.ogr.bridj.OgrLibrary.*;
+
import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
import java.text.DateFormat;
+import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
-import org.gdal.ogr.FeatureDefn;
-import org.gdal.ogr.FieldDefn;
-import org.gdal.ogr.ogr;
+import org.bridj.Pointer;
import org.geotools.data.DataSourceException;
+import org.geotools.data.ogr.bridj.OgrLibrary.OGRFieldType;
import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.util.Converters;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
@@ -64,11 +76,31 @@
DateFormat timeFormat = new SimpleDateFormat("hh:mm:ss");
- public FeatureMapper(SimpleFeatureType schema, GeometryFactory geomFactory) {
- this.schema = schema;
+ HashMap<String, Integer> attributeIndexes;
+
+ /**
+ * TODO: this is subscepitble to changes to the Locale in Java that might not affect
+ * the C code... we should probably figure out a way to get the OS level locale?
+ */
+ static final DecimalFormatSymbols DECIMAL_SYMBOLS = new DecimalFormatSymbols();
+
+ public FeatureMapper(SimpleFeatureType targetSchema, Pointer layer, GeometryFactory geomFactory) {
+ this.schema = targetSchema;
this.builder = new SimpleFeatureBuilder(schema);
- this.geomMapper = new GeometryMapper(geomFactory);
+ this.geomMapper = new GeometryMapper.WKB(geomFactory);
this.geomFactory = geomFactory;
+
+ attributeIndexes = new HashMap<String, Integer>();
+ Pointer layerDefinition = OGR_L_GetLayerDefn(layer);
+ int size = OGR_FD_GetFieldCount(layerDefinition);
+ for(int i = 0; i < size; i++) {
+ Pointer field = OGR_FD_GetFieldDefn(layerDefinition, i);
+ Pointer<Byte> namePtr = OGR_Fld_GetNameRef(field);
+ String name = namePtr.getCString();
+ if(targetSchema.getDescriptor(name) != null) {
+ attributeIndexes.put(name, i);
+ }
+ }
}
/**
@@ -79,7 +111,7 @@
* @return
* @throws IOException
*/
- SimpleFeature convertOgrFeature(org.gdal.ogr.Feature ogrFeature)
+ SimpleFeature convertOgrFeature(Pointer<?> ogrFeature)
throws IOException {
// Extract all attributes (do not assume any specific order, the feature
// type may have been re-ordered by the Query)
@@ -89,16 +121,7 @@
// which extraction method to call
for (int i = 0; i < attributes.length; i++) {
AttributeDescriptor at = schema.getDescriptor(i);
- if (at instanceof GeometryDescriptor) {
- org.gdal.ogr.Geometry ogrGeometry = ogrFeature.GetGeometryRef();
- try {
- builder.add(fixGeometryType(geomMapper.parseOgrGeometry(ogrGeometry), at));
- } finally {
- ogrGeometry.delete();
- }
- } else {
- builder.add(getOgrField(at, ogrFeature));
- }
+ builder.add(getOgrField(at, ogrFeature));
}
// .. gather the FID
@@ -115,46 +138,73 @@
* @return
* @throws DataSourceException
*/
- org.gdal.ogr.Feature convertGTFeature(FeatureDefn ogrSchema, SimpleFeature feature)
+ Pointer convertGTFeature(Pointer featureDefinition, SimpleFeature feature)
throws IOException {
// create a new empty OGR feature
- org.gdal.ogr.Feature result = new org.gdal.ogr.Feature(ogrSchema);
+ Pointer ogrFeature = OGR_F_Create(featureDefinition);
// go thru GeoTools feature attributes, and convert
SimpleFeatureType schema = feature.getFeatureType();
for (int i = 0, j = 0; i < schema.getAttributeCount(); i++) {
- AttributeDescriptor at = schema.getDescriptor(i);
Object attribute = feature.getAttribute(i);
- if (at instanceof GeometryDescriptor) {
+ if (attribute instanceof Geometry) {
// using setGeoemtryDirectly the feature becomes the owner of the generated
// OGR geometry and we don't have to .delete() it (it's faster, too)
- result.SetGeometryDirectly(geomMapper.parseGTGeometry((Geometry) attribute));
- continue;
+ Pointer geometry = geomMapper.parseGTGeometry((Geometry) attribute);
+ OGR_F_SetGeometryDirectly(ogrFeature, geometry);
+ } else {
+ setFieldValue(featureDefinition, ogrFeature, j, attribute);
+ j++;
}
+ }
- if (attribute == null) {
- result.UnsetField(j);
+ return ogrFeature;
+ }
+
+ static void setFieldValue(Pointer featureDefinition, Pointer ogrFeature, int fieldIdx,
+ Object value) throws IOException {
+ if (value == null) {
+ OGR_F_UnsetField(ogrFeature, fieldIdx);
+ } else {
+ Pointer fieldDefinition = OGR_FD_GetFieldDefn(featureDefinition, fieldIdx);
+ long ogrType = OGR_Fld_GetType(fieldDefinition).value();
+ if (ogrType == OGRFieldType.OFTInteger.value()) {
+ OGR_F_SetFieldInteger(ogrFeature, fieldIdx, ((Number) value).intValue());
+ } else if (ogrType == OGRFieldType.OFTReal.value()) {
+ OGR_F_SetFieldDouble(ogrFeature, fieldIdx, ((Number) value).doubleValue());
+ } else if (ogrType == OGRFieldType.OFTBinary.value()) {
+ byte[] attValue = (byte[]) value;
+ OGR_F_SetFieldBinary(ogrFeature, fieldIdx, attValue.length, pointerToBytes(attValue));
+ } else if (ogrType == OGRFieldType.OFTDate.value()) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime((Date) value);
+ int year = cal.get(Calendar.YEAR);
+ int month = cal.get(Calendar.MONTH);
+ int day = cal.get(Calendar.DAY_OF_MONTH);
+ OGR_F_SetFieldDateTime(ogrFeature, fieldIdx, year, month, day, 0, 0, 0, 0);
+ } else if (ogrType == OGRFieldType.OFTTime.value()) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime((Date) value);
+ int hour = cal.get(Calendar.HOUR_OF_DAY);
+ int minute = cal.get(Calendar.MINUTE);
+ int second = cal.get(Calendar.SECOND);
+ OGR_F_SetFieldDateTime(ogrFeature, fieldIdx, 0, 0, 0, hour, minute, second, 0);
+ } else if (ogrType == OGRFieldType.OFTDateTime.value()) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime((Date) value);
+ int year = cal.get(Calendar.YEAR);
+ int month = cal.get(Calendar.MONTH);
+ int day = cal.get(Calendar.DAY_OF_MONTH);
+ int hour = cal.get(Calendar.HOUR_OF_DAY);
+ int minute = cal.get(Calendar.MINUTE);
+ int second = cal.get(Calendar.SECOND);
+ OGR_F_SetFieldDateTime(ogrFeature, fieldIdx, year, month, day, hour, minute, second, 0);
} else {
- final FieldDefn ogrField = ogrSchema.GetFieldDefn(j);
- final int ogrType = ogrField.GetFieldType();
- ogrField.delete();
- if (ogrType == ogr.OFTInteger)
- result.SetField(j, ((Number) attribute).intValue());
- else if (ogrType == ogr.OFTReal)
- result.SetField(j, ((Number) attribute).doubleValue());
- else if (ogrType == ogr.OFTDateTime)
- result.SetField(j, dateTimeFormat.format((java.util.Date) attribute));
- else if (ogrType == ogr.OFTDate)
- result.SetField(j, dateFormat.format((java.util.Date) attribute));
- else if (ogrType == ogr.OFTTime)
- result.SetField(j, timeFormat.format((java.util.Date) attribute));
- else
- result.SetField(j, attribute.toString());
+ // anything else we treat as a string
+ String str = Converters.convert(value, String.class);
+ OGR_F_SetFieldString(ogrFeature, fieldIdx, pointerToCString(str));
}
- j++;
}
-
- return result;
}
/**
@@ -191,41 +241,65 @@
* @param ad
* @return
*/
- Object getOgrField(AttributeDescriptor ad, org.gdal.ogr.Feature ogrFeature) throws IOException {
- String name = ad.getLocalName();
- Class clazz = ad.getType().getBinding();
+ Object getOgrField(AttributeDescriptor ad, Pointer<?> ogrFeature) throws IOException {
+ if(ad instanceof GeometryDescriptor) {
+ // gets the geometry as a reference, we don't own it, we should not deallocate it
+ Pointer<?> ogrGeometry = OGR_F_GetGeometryRef(ogrFeature);
+ return fixGeometryType(geomMapper.parseOgrGeometry(ogrGeometry), ad);
+ }
+
+ Integer idx = attributeIndexes.get(ad.getLocalName());
// check for null fields
- if (!ogrFeature.IsFieldSet(name))
+ if (idx == null || OGR_F_IsFieldSet(ogrFeature, idx) == 0) {
return null;
+ }
// hum, ok try and parse it
+ Class clazz = ad.getType().getBinding();
if (clazz.equals(String.class)) {
- return ogrFeature.GetFieldAsString(name);
+ return OGR_F_GetFieldAsString(ogrFeature, idx).getCString();
+ } else if (clazz.equals(Byte.class)) {
+ return (byte) OGR_F_GetFieldAsInteger(ogrFeature, idx);
+ } else if (clazz.equals(Short.class)) {
+ return (short) OGR_F_GetFieldAsInteger(ogrFeature, idx);
} else if (clazz.equals(Integer.class)) {
- return new Integer(ogrFeature.GetFieldAsInteger(name));
+ return OGR_F_GetFieldAsInteger(ogrFeature, idx);
+ } else if (clazz.equals(Long.class)) {
+ String value = OGR_F_GetFieldAsString(ogrFeature, idx).getCString();
+ return new Long(value);
+ } else if (clazz.equals(BigInteger.class)) {
+ String value = OGR_F_GetFieldAsString(ogrFeature, idx).getCString();
+ return new BigInteger(value);
} else if (clazz.equals(Double.class)) {
- return new Double(ogrFeature.GetFieldAsDouble(name));
+ return OGR_F_GetFieldAsDouble(ogrFeature, idx);
} else if (clazz.equals(Float.class)) {
- return new Float(ogrFeature.GetFieldAsDouble(name));
- } else if (clazz.equals(Integer.class)) {
- return new Integer(ogrFeature.GetFieldAsInteger(name));
+ return (float) OGR_F_GetFieldAsDouble(ogrFeature, idx);
+ } else if (clazz.equals(BigDecimal.class)) {
+ String value = OGR_F_GetFieldAsString(ogrFeature, idx).getCString().trim();
+ char separator = DECIMAL_SYMBOLS.getDecimalSeparator();
+ if(separator != '.') {
+ value = value.replace(separator, '.');
+ }
+ return new BigDecimal(value);
+ } else if (clazz.equals(java.sql.Date.class)) {
+ Calendar cal = getDateField(ogrFeature, idx);
+ cal.clear(Calendar.HOUR_OF_DAY);
+ cal.clear(Calendar.MINUTE);
+ cal.clear(Calendar.SECOND);
+ return new java.sql.Date(cal.getTimeInMillis());
+ } else if (clazz.equals(java.sql.Time.class)) {
+ Calendar cal = getDateField(ogrFeature, idx);
+ cal.clear(Calendar.YEAR);
+ cal.clear(Calendar.MONTH);
+ cal.clear(Calendar.DAY_OF_MONTH);
+ return new java.sql.Time(cal.getTimeInMillis());
+ } else if (clazz.equals(java.sql.Timestamp.class)) {
+ Calendar cal = getDateField(ogrFeature, idx);
+ return new java.sql.Time(cal.getTimeInMillis());
} else if (clazz.equals(java.util.Date.class)) {
- String date = ogrFeature.GetFieldAsString(name);
- if (date == null || date.trim().equals(""))
- return null;
- int ogrType = ogrFeature.GetFieldType(name);
- try {
- if (ogrType == ogr.OFTDateTime)
- return dateTimeFormat.parse(date);
- else if (ogrType == ogr.OFTDate)
- return dateFormat.parse(date);
- else if (ogrType == ogr.OFTTime)
- return timeFormat.parse(date);
- } catch (java.text.ParseException e) {
- throw new DataSourceException("Could not parse date value", e);
- }
- throw new IOException("Date attribute, but field type is not compatible: " + ogrType);
+ Calendar cal = getDateField(ogrFeature, idx);
+ return cal.getTime();
} else {
throw new IllegalArgumentException("Don't know how to read " + clazz.getName()
+ " fields");
@@ -233,14 +307,56 @@
}
/**
+ * Reads a date field from the OGR api
+ * @param ogrFeature
+ * @param idx
+ * @return
+ */
+ private Calendar getDateField(Pointer<?> ogrFeature, Integer idx) {
+ Pointer<Integer> year = allocateInt();
+ Pointer<Integer> month = allocateInt();
+ Pointer<Integer> day = allocateInt();
+ Pointer<Integer> hour = allocateInt();
+ Pointer<Integer> minute = allocateInt();
+ Pointer<Integer> second = allocateInt();
+ Pointer<Integer> timeZone = allocateInt();
+
+ OGR_F_GetFieldAsDateTime(ogrFeature, idx, year, month, day, hour, minute, second, timeZone);
+
+ Calendar cal = Calendar.getInstance();
+ // from ogr_core.h
+ // 0=unknown, 1=localtime(ambiguous), 100=GMT, 104=GMT+1, 80=GMT-5, etc
+ int tz = timeZone.getInt();
+ if(tz != 0 && tz != 1) {
+ int offset = tz - 100 / 4;
+ if(offset < 0) {
+ cal.setTimeZone(TimeZone.getTimeZone("GMT" + offset));
+ } else if(offset == 0) {
+ cal.setTimeZone(TimeZone.getTimeZone("GMT"));
+ } else {
+ cal.setTimeZone(TimeZone.getTimeZone("GMT+" + offset));
+ }
+ }
+ cal.clear();
+ cal.set(Calendar.YEAR, year.getInt());
+ cal.set(Calendar.MONTH, month.getInt());
+ cal.set(Calendar.DAY_OF_MONTH, day.getInt());
+ cal.set(Calendar.HOUR_OF_DAY, hour.getInt());
+ cal.set(Calendar.MINUTE, minute.getInt());
+ cal.set(Calendar.SECOND, second.getInt());
+ return cal;
+ }
+
+ /**
* Generates a GT2 feature id given its feature type and an OGR feature
*
* @param schema
* @param ogrFeature
* @return
*/
- String convertOGRFID(SimpleFeatureType schema, org.gdal.ogr.Feature ogrFeature) {
- return schema.getTypeName() + "." + ogrFeature.GetFID();
+ String convertOGRFID(SimpleFeatureType schema, Pointer<?> ogrFeature) {
+ long id = OGR_F_GetFID(ogrFeature);
+ return schema.getTypeName() + "." + id;
}
/**
@@ -249,9 +365,9 @@
* @param feature
* @return
*/
- int convertGTFID(SimpleFeature feature) {
+ long convertGTFID(SimpleFeature feature) {
String id = feature.getID();
- return Integer.parseInt(id.substring(id.indexOf(".") + 1));
+ return Long.parseLong(id.substring(id.indexOf(".") + 1));
}
}
Modified: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/GeometryMapper.java
===================================================================
--- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/GeometryMapper.java 2012-01-12 07:30:49 UTC (rev 38479)
+++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/GeometryMapper.java 2012-01-15 17:55:59 UTC (rev 38480)
@@ -16,10 +16,14 @@
*/
package org.geotools.data.ogr;
+import static org.bridj.Pointer.*;
+import static org.geotools.data.ogr.OGRUtils.*;
+import static org.geotools.data.ogr.bridj.OgrLibrary.*;
+
import java.io.IOException;
-import org.gdal.ogr.ogr;
-import org.geotools.data.DataSourceException;
+import org.bridj.Pointer;
+import org.geotools.data.ogr.bridj.OgrLibrary.OGRwkbByteOrder;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
@@ -31,99 +35,99 @@
/**
* Converts between JTS and OGR geometries
- * @author Andrea Aime - OpenGeo
- *
- * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/build/maven/javadoc/../../../modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/GeometryMapper.java $
+ *
+ * @author Andrea Aime - GeoSolutions
+ *
+ *
+ * @source $URL:
+ * http://svn.osgeo.org/geotools/trunk/modules/unsupported/ogr/src/main/java/org/geotools
+ * /data/ogr/GeometryMapper.java $
*/
-public class GeometryMapper {
- /**
- * From ogr_core.h, the byte order constants
- */
- static final int WKB_XDR = 1;
+@SuppressWarnings("rawtypes")
+abstract class GeometryMapper {
- /**
- * Enables usage of WKB encoding for OGR/Java Geometry conversion. At the time of writing, it
- * cannot be used because it'll bring the virtual machine down (yes, a real crash...)
- */
- static final boolean USE_WKB = true;
+ abstract Geometry parseOgrGeometry(Pointer geom) throws IOException;
- GeometryFactory geomFactory;
+ abstract Pointer parseGTGeometry(Geometry geometry) throws IOException;
- WKBReader wkbReader;
+ static class WKB extends GeometryMapper {
+ GeometryFactory geomFactory;
- WKTReader wktReader;
+ WKBReader wkbReader;
- WKBWriter wkbWriter;
+ WKBWriter wkbWriter;
- WKTWriter wktWriter;
-
- public GeometryMapper(GeometryFactory geomFactory) {
- this.geomFactory = geomFactory;
- if (USE_WKB) {
+ public WKB(GeometryFactory geomFactory) {
+ this.geomFactory = geomFactory;
this.wkbReader = new WKBReader(geomFactory);
this.wkbWriter = new WKBWriter();
- } else {
- this.wktReader = new WKTReader(geomFactory);
- this.wktWriter = new WKTWriter();
}
- }
-
- /**
- * Reads the current feature's geometry using wkb encoding. A wkbReader should be provided since
- * it's not thread safe by design.
- *
- * @throws IOException
- */
- Geometry parseOgrGeometry(org.gdal.ogr.Geometry geom) throws IOException {
- // Extract the geometry using either WKT or WKB. Rationale: the SWIG
- // bindings do not provide subclasses. Even if they did, going thru the
- // JNI barrier often is expensive, so it's better to gather the geometry
- // is a single call
- if (USE_WKB) {
- int wkbSize = geom.WkbSize();
- // the gdal interface uses a char* type, maybe because in C it's
- // unsigned and has
- // the same size as a byte, unfortunately this means we have to
- // unpack it
- // to byte format by doing bit masking and shifting
- byte[] byteBuffer = new byte[wkbSize];
- geom.ExportToWkb(byteBuffer, WKB_XDR);
+ /**
+ * Reads the current feature's geometry using wkb encoding. A wkbReader should be provided
+ * since it's not thread safe by design.
+ *
+ * @throws IOException
+ */
+ Geometry parseOgrGeometry(Pointer geom) throws IOException {
+ int wkbSize = OGR_G_WkbSize(geom);
+ Pointer<Byte> ptrBytes = pointerToBytes(new byte[wkbSize]);
+ checkError(OGR_G_ExportToWkb(geom, OGRwkbByteOrder.wkbXDR, ptrBytes));
try {
- Geometry g = wkbReader.read(byteBuffer);
+ byte[] wkb = ptrBytes.getBytes();
+ Geometry g = wkbReader.read(wkb);
return g;
} catch (ParseException pe) {
- throw new RuntimeException(
- "Could not parse the current Geometry in WKB format.", pe);
+ throw (IOException) new IOException("Could not parse the current Geometry in WKB format.").initCause(pe);
}
- } else {
- String[] stringArray = new String[1];
- geom.ExportToWkt(stringArray);
+ }
+
+ Pointer parseGTGeometry(Geometry geometry) throws IOException {
+ byte[] wkb = wkbWriter.write(geometry);
+ Pointer<Pointer<?>> ptr = allocatePointer();
+ checkError(OGR_G_CreateFromWkb(pointerToBytes(wkb), null, ptr, wkb.length));
+ return ptr.getPointer(Pointer.class);
+ }
+
+ }
+
+ static class WKT extends GeometryMapper {
+ GeometryFactory geomFactory;
+
+ WKTReader wktReader;
+
+ WKTWriter wktWriter;
+
+ public WKT(GeometryFactory geomFactory) {
+ this.geomFactory = geomFactory;
+ this.wktReader = new WKTReader(geomFactory);
+ this.wktWriter = new WKTWriter();
+ }
+
+ /**
+ * Reads the current feature's geometry using wkb encoding. A wkbReader should be provided
+ * since it's not thread safe by design.
+ *
+ * @throws IOException
+ */
+ Geometry parseOgrGeometry(Pointer geom) throws IOException {
+ Pointer<Pointer<Byte>> wktPtr = allocatePointer(Byte.class);
+ checkError(OGR_G_ExportToWkt(geom, wktPtr));
try {
- return wktReader.read(stringArray[0]);
+ String wkt = wktPtr.getPointer(Byte.class).getCString();
+ return wktReader.read(wkt);
} catch (ParseException pe) {
- throw new RuntimeException(
- "Could not parse the current Geometry in WKB format.", pe);
+ throw (IOException) new IOException("Could not parse the current Geometry in WKT format.").initCause(pe);
}
}
- }
- org.gdal.ogr.Geometry parseGTGeometry(Geometry geometry) throws RuntimeException {
- final org.gdal.ogr.Geometry ogrGeom;
- if (USE_WKB) {
- byte[] wkb = wkbWriter.write(geometry);
- ogrGeom = ogr.CreateGeometryFromWkb(wkb, null);
- if (ogrGeom == null)
- throw new RuntimeException(
- "Could not turn JTS geometry into an OGR one thought WKB");
- } else {
+ Pointer parseGTGeometry(Geometry geometry) throws IOException {
String wkt = wktWriter.write(geometry);
- ogrGeom = ogr.CreateGeometryFromWkt(wkt, null);
- if (ogrGeom == null)
- throw new RuntimeException(
- "Could not turn JTS geometry into an OGR one thought WKT");
+ Pointer<Pointer<Byte>> ptr = pointerToPointer(pointerToCString(wkt));
+ Pointer<Pointer<?>> geom = allocatePointer();
+ checkError(OGR_G_CreateFromWkt(ptr, null, geom));
+ return geom.getPointer(Pointer.class);
}
- return ogrGeom;
+
}
-
}
Modified: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRDataStore.java
===================================================================
--- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRDataStore.java 2012-01-12 07:30:49 UTC (rev 38479)
+++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRDataStore.java 2012-01-15 17:55:59 UTC (rev 38480)
@@ -16,428 +16,156 @@
*/
package org.geotools.data.ogr;
+import static org.bridj.Pointer.*;
+import static org.geotools.data.ogr.OGRUtils.*;
+import static org.geotools.data.ogr.bridj.CplErrorLibrary.*;
+import static org.geotools.data.ogr.bridj.OgrLibrary.*;
+
import java.io.IOException;
-import java.io.StringWriter;
-import java.math.BigDecimal;
-import java.math.BigInteger;
import java.net.URI;
-import java.util.Arrays;
-import java.util.Vector;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
-import org.gdal.gdal.gdal;
-import org.gdal.ogr.DataSource;
-import org.gdal.ogr.Driver;
-import org.gdal.ogr.FeatureDefn;
-import org.gdal.ogr.FieldDefn;
-import org.gdal.ogr.Layer;
-import org.gdal.ogr.ogr;
-import org.gdal.osr.SpatialReference;
-import org.geotools.data.AbstractDataStore;
+import org.bridj.Pointer;
+import org.bridj.ValuedEnum;
import org.geotools.data.DataSourceException;
-import org.geotools.data.FeatureReader;
-import org.geotools.data.FeatureWriter;
import org.geotools.data.Query;
-import org.geotools.data.Transaction;
-import org.geotools.data.jdbc.FilterToSQL;
-import org.geotools.factory.FactoryRegistryException;
-import org.geotools.feature.AttributeTypeBuilder;
-import org.geotools.feature.FeatureTypes;
-import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
-import org.geotools.feature.type.BasicFeatureTypes;
-import org.geotools.filter.FilterCapabilities;
-import org.geotools.filter.visitor.PostPreProcessFilterSplittingVisitor;
-import org.geotools.geometry.jts.ReferencedEnvelope;
-import org.geotools.referencing.CRS;
-import org.geotools.resources.Classes;
+import org.geotools.data.ogr.bridj.OgrLibrary.OGRwkbGeometryType;
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureIterator;
+import org.geotools.data.store.ContentDataStore;
+import org.geotools.data.store.ContentEntry;
+import org.geotools.data.store.ContentFeatureSource;
+import org.geotools.feature.NameImpl;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.GeometryDescriptor;
-import org.opengis.feature.type.GeometryType;
-import org.opengis.filter.And;
-import org.opengis.filter.Filter;
-import org.opengis.filter.Or;
-import org.opengis.filter.PropertyIsEqualTo;
-import org.opengis.filter.PropertyIsGreaterThan;
-import org.opengis.filter.PropertyIsGreaterThanOrEqualTo;
-import org.opengis.filter.PropertyIsLessThan;
-import org.opengis.filter.PropertyIsLessThanOrEqualTo;
-import org.opengis.filter.PropertyIsNotEqualTo;
-import org.opengis.filter.expression.Expression;
-import org.opengis.filter.expression.Literal;
-import org.opengis.filter.expression.PropertyName;
-import org.opengis.filter.spatial.BBOX;
-import org.opengis.filter.spatial.BinarySpatialOperator;
-import org.opengis.filter.spatial.Contains;
-import org.opengis.filter.spatial.Crosses;
-import org.opengis.filter.spatial.Equals;
-import org.opengis.filter.spatial.Intersects;
-import org.opengis.filter.spatial.Overlaps;
-import org.opengis.filter.spatial.Touches;
-import org.opengis.filter.spatial.Within;
-import org.opengis.referencing.FactoryException;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.feature.type.Name;
import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.geom.GeometryCollection;
-import com.vividsolutions.jts.geom.LineString;
-import com.vividsolutions.jts.geom.MultiLineString;
-import com.vividsolutions.jts.geom.MultiPoint;
-import com.vividsolutions.jts.geom.MultiPolygon;
-import com.vividsolutions.jts.geom.Point;
-import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.geom.GeometryFactory;
/**
- * A datastore based on the the <a href="http://www.gdal.org/ogr">OGR</a> spatial data abstraction
- * library
+ * A data store based on the OGR native library, bound to it via <a
+ * href="http://code.google.com/p/bridj/">BridJ</a>
*
- * @author Andrea Aime - OpenGeo
- *
- *
- * @source $URL$
- * http://svn.osgeo.org/geotools/trunk/modules/unsupported/ogr/src/main/java/org/geotools
- * /data/ogr/OGRDataStore.java $
+ * @author Andrea Aime - GeoSolutions
*/
-public class OGRDataStore extends AbstractDataStore {
- /** C compatible FALSE */
- static final int FALSE = 0;
+@SuppressWarnings("rawtypes")
+public class OGRDataStore extends ContentDataStore {
- /** C compatible TRUE */
- static final int TRUE = 1;
-
- static final FilterCapabilities ATTRIBUTE_FILTER_CAPABILITIES;
-
- static final FilterCapabilities GEOMETRY_FILTER_CAPABILITIES;
-
static {
- ATTRIBUTE_FILTER_CAPABILITIES = new FilterCapabilities();
- ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsEqualTo.class);
- ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsNotEqualTo.class);
- ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsGreaterThan.class);
- ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsLessThan.class);
- ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsGreaterThanOrEqualTo.class);
- ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsLessThanOrEqualTo.class);
- ATTRIBUTE_FILTER_CAPABILITIES.addType(Or.class);
- ATTRIBUTE_FILTER_CAPABILITIES.addType(And.class);
+ GdalInit.init();
- // have the capabilities extract any filter that can use geometric intersection
- // as its base
- GEOMETRY_FILTER_CAPABILITIES = new FilterCapabilities();
- GEOMETRY_FILTER_CAPABILITIES.addType(BBOX.class);
- GEOMETRY_FILTER_CAPABILITIES.addType(Contains.class);
- GEOMETRY_FILTER_CAPABILITIES.addType(Crosses.class);
- GEOMETRY_FILTER_CAPABILITIES.addType(Equals.class);
- GEOMETRY_FILTER_CAPABILITIES.addType(Intersects.class);
- GEOMETRY_FILTER_CAPABILITIES.addType(Overlaps.class);
- GEOMETRY_FILTER_CAPABILITIES.addType(Touches.class);
- GEOMETRY_FILTER_CAPABILITIES.addType(Within.class);
- }
-
- /**
- * The OGRwkbGeometryType enum from ogr_core.h, reduced to represent only 2D classes (I hope the
- * 2.5D will be handled transparently by JTS)
- */
- static final Class[] OGR_GEOM_TYPES = new Class[] { //
- Geometry.class, // wkbUnknown = 0
- Point.class, // wkbPoint = 1
- MultiLineString.class, // wkbLineString = 2,
- MultiPolygon.class, // wkbPolygon = 3,
- MultiPoint.class, // wkbMultiPoint = 4,
- MultiLineString.class, // wkbMultiLineString = 5,
- MultiPolygon.class, // wkbMultiPolygon = 6,
- GeometryCollection.class, // wkbGeometryCollection = 7
- };
-
- /**
- * The source name that OGR should open and handle
- */
- private String ogrSourceName;
-
- /**
- * Datastore namespace
- */
- private URI namespace;
-
- /**
- * OGR driver to be used for the creation of new data sources
- */
- private String ogrDriverName;
-
- static {
// perform OGR format registration once
- if (ogr.GetDriverCount() == 0)
- ogr.RegisterAll();
+ if (OGRGetDriverCount() == 0) {
+ OGRRegisterAll();
+ }
}
- /**
- * Creates a new OGRDataStore
- *
- * @param ogrSourceName
- * a references to the source that needs to be opened. May be a file system path, or
- * a database reference. See the OGR driver documentation for valid formats of this
- * string.
- */
+ String ogrSourceName;
- public OGRDataStore(String ogrSourceName, String ogrDriverName, URI namespace)
- throws IOException {
- this.ogrSourceName = ogrSourceName;
- this.ogrDriverName = ogrDriverName;
- this.namespace = (namespace != null) ? namespace : FeatureTypes.DEFAULT_NAMESPACE;
- int update = FALSE;
- if (ogrDriverName == null) {
- DataSource ds = getOGRDataSource(update);
- ds.delete();
+ String ogrDriver;
+
+ public OGRDataStore(String ogrName, String ogrDriver, URI namespace) {
+ if (namespace != null) {
+ setNamespaceURI(namespace.toString());
}
+ this.ogrSourceName = ogrName;
+ this.ogrDriver = ogrDriver;
}
-
+
@Override
- protected FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(String typeName)
- throws IOException {
- return getFeatureReader(typeName, Query.ALL, false);
- }
+ protected List<Name> createTypeNames() throws IOException {
+ Pointer dataSource = null;
+ Pointer layer = null;
+ try {
+ dataSource = openOGRDataSource(false);
- protected FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(String typeName,
- Query query) throws IOException {
- return getFeatureReader(typeName, query, false);
- }
-
- protected FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(String typeName,
- Query query, boolean openForUpdate)
- throws IOException {
- DataSource ds = getOGRDataSource(openForUpdate ? TRUE : FALSE);
- Layer layer = getOGRLayer(ds, typeName);
-
- // handle filtering if possible
- SimpleFeatureType schema = getSchema(typeName);
- Filter filter = query.getFilter();
- org.gdal.ogr.Geometry spatialFilter = getSpatialFilter(schema, filter);
- if(spatialFilter != null)
- layer.SetSpatialFilter(spatialFilter);
- String attributeFilter = getAttributeFilter(schema, filter);
- if(attributeFilter != null)
- layer.SetAttributeFilter(attributeFilter);
-
- return new OGRFeatureReader(ds, layer, schema);
- }
-
- /**
- * Parses the Geotools filter and tries to extract an intersecting geometry that
- * can be used as the OGR spatial filter
- * @param schema
- * @param filter
- * @return
- */
- protected org.gdal.ogr.Geometry getSpatialFilter(SimpleFeatureType schema, Filter filter) {
- // TODO: switch to the non deprecated splitter (that no one seems to be using)
- PostPreProcessFilterSplittingVisitor visitor = new PostPreProcessFilterSplittingVisitor(GEOMETRY_FILTER_CAPABILITIES, schema, null);
- filter.accept(visitor, null);
- Filter preFilter = visitor.getFilterPre();
- if(preFilter instanceof BinarySpatialOperator) {
- BinarySpatialOperator bso = ((BinarySpatialOperator) preFilter);
- Expression geomExpression = null;
- if(bso.getExpression1() instanceof PropertyName && bso.getExpression2() instanceof Literal) {
- geomExpression = bso.getExpression2();
- } else if(bso.getExpression1() instanceof Literal && bso.getExpression2() instanceof PropertyName) {
- geomExpression = bso.getExpression1();
+ List<Name> result = new ArrayList<Name>();
+ int count = OGR_DS_GetLayerCount(dataSource);
+ for (int i = 0; i < count; i++) {
+ layer = OGR_DS_GetLayer(dataSource, i);
+ String name = getLayerName(layer);
+ if (name != null) {
+ result.add(new NameImpl(getNamespaceURI(), name));
+ }
+ OGRUtils.releaseLayer(layer);
}
- if(geomExpression != null) {
- Geometry geom = geomExpression.evaluate(null, Geometry.class);
- if(geom != null)
- return new GeometryMapper(geom.getFactory()).parseGTGeometry(geom);
- }
+ return result;
+ } catch (IOException e) {
+ return Collections.emptyList();
+ } finally {
+ OGRUtils.releaseDataSource(dataSource);
+ OGRUtils.releaseLayer(layer);
}
- return null;
}
-
- /**
- * Parses the GeoTools filter and tries to extract an SQL expression that can
- * be used as the OGR attribute filter
- * @param schema
- * @param filter
- * @return
- */
- protected String getAttributeFilter(SimpleFeatureType schema, Filter filter) {
- // TODO: switch to the non deprecated splitter (that no one seems to be using)
- PostPreProcessFilterSplittingVisitor visitor = new PostPreProcessFilterSplittingVisitor(ATTRIBUTE_FILTER_CAPABILITIES, schema, null);
- filter.accept(visitor, null);
- Filter preFilter = visitor.getFilterPre();
- if(preFilter != Filter.EXCLUDE && preFilter != Filter.INCLUDE) {
- StringWriter writer = new StringWriter();
- FilterToSQL sqlConverter = new FilterToSQL(writer);
- preFilter.accept(sqlConverter, null);
- return writer.getBuffer().toString();
- }
- return null;
- }
- public SimpleFeatureType getSchema(String typeName) throws IOException {
- DataSource ds = getOGRDataSource(FALSE);
- Layer layer = getOGRLayer(ds, typeName);
- if (layer == null) {
- ds.delete();
- throw new IOException("No such type : " + typeName);
- }
- FeatureDefn featureDef = null;
- try {
- featureDef = layer.GetLayerDefn();
-
- SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
- AttributeTypeBuilder abuilder = new AttributeTypeBuilder();
- builder.setName(typeName);
- builder.setNamespaceURI(namespace);
-
- // handle the geometry
- CoordinateReferenceSystem crs = getCRS(layer);
- Class geomClass = getGeometryClass(featureDef.GetGeomType());
- abuilder.setName(Classes.getShortName( geomClass ));
- abuilder.setNillable(true);
- abuilder.setCRS(crs);
- abuilder.setBinding(geomClass);
- GeometryType geometryType = abuilder.buildGeometryType();
- builder.add(abuilder.buildDescriptor(
- BasicFeatureTypes.GEOMETRY_ATTRIBUTE_NAME, geometryType));
-
-// builder.add("the_geom", geomClass, crs);
-
- // compute a default parent feature type
- if ((geomClass == Point.class) || (geomClass == MultiPoint.class)) {
- builder.setSuperType(BasicFeatureTypes.POINT);
- } else if ((geomClass == Polygon.class) || (geomClass == MultiPolygon.class)) {
- builder.setSuperType(BasicFeatureTypes.POLYGON);
- } else if ((geomClass == LineString.class) || (geomClass == MultiLineString.class)) {
- builder.setSuperType(BasicFeatureTypes.LINE);
+ Pointer openOGRDataSource(boolean update) throws IOException {
+ Pointer ds = null;
+ Pointer<Byte> sourcePtr = pointerToCString(ogrSourceName);
+ int mode = update ? 1 : 0;
+ if (ogrDriver != null) {
+ Pointer driver = OGRGetDriverByName(pointerToCString(ogrDriver));
+ if (driver == null) {
+ throw new IOException("Could not find a driver named " + driver);
}
-
- // handle the other fields
- for (int i = 1; i < featureDef.GetFieldCount() + 1; i++) {
- FieldDefn fd = featureDef.GetFieldDefn(i - 1);
- builder.length(fd.GetWidth());
- builder.add(fd.GetNameRef(), getFieldClass(fd));
- fd.delete();
+ ds = OGR_Dr_Open(driver, sourcePtr, mode);
+ if (ds == null) {
+ throw new IOException("OGR could not open '" + ogrSourceName + "' in "
+ + (update ? "read-write" : "read-only") + " mode with driver " + ogrDriver);
}
-
- // finally build the geometry type
- return builder.buildFeatureType();
- } catch (FactoryException e) {
- throw new DataSourceException("Could not determine geometry SRS", e);
- } catch (FactoryRegistryException e) {
- throw new DataSourceException("Could not create feature type", e);
- } finally {
- if (featureDef != null)
- featureDef.delete();
- if (layer != null)
- layer.delete();
- if (ds != null)
- ds.delete();
+ } else {
+ ds = OGROpenShared(sourcePtr, mode, null);
+ if (ds == null) {
+ throw new IOException("OGR could not open '" + ogrSourceName + "' in "
+ + (update ? "read-write" : "read-only") + " mode");
+ }
}
+ return ds;
}
- public String[] getTypeNames() throws IOException {
- DataSource ds;
- try {
- ds = getOGRDataSource(FALSE);
- } catch (IOException e) {
- return new String[0];
+ Pointer openOGRLayer(Pointer dataSource, String layerName) throws IOException {
+ Pointer layer = OGR_DS_GetLayerByName(dataSource, pointerToCString(layerName));
+ if (layer == null) {
+ throw new IOException("OGR could not find layer '" + layerName + "'");
}
- String[] typeNames = new String[ds.GetLayerCount()];
- for (int i = 0; i < typeNames.length; i++) {
- Layer l = ds.GetLayerByIndex(i);
- typeNames[i] = l.GetName();
- l.delete();
- }
- ds.delete();
- return typeNames;
+ return layer;
}
- protected int getCount(Query query) throws IOException {
- if (!Filter.INCLUDE.equals(query.getFilter()))
- return -1;
-
- DataSource ds = getOGRDataSource(FALSE);
- Layer l = getOGRLayer(ds, query.getTypeName());
- if (l == null)
- throw new IOException("Unknown feature type: " + query.getTypeName());
-
- // go for the quick computation, return -1 otherwise
- int count = l.GetFeatureCount(FALSE);
- l.delete();
- ds.delete();
- return count;
- }
-
- protected FeatureWriter createFeatureWriter(String typeName, Transaction transaction)
- throws IOException {
- if (supportsInPlaceWrite(typeName)) {
- OGRFeatureReader reader = (OGRFeatureReader) getFeatureReader(typeName, Query.ALL, true);
- return new OGRDirectFeatureWriter(reader);
+ @Override
+ protected ContentFeatureSource createFeatureSource(ContentEntry entry) throws IOException {
+ if (supportsInPlaceWrite(entry.getTypeName())) {
+ return new OGRFeatureStore(entry, Query.ALL);
} else {
- throw new UnsupportedOperationException(
- "This file format does not support in place write, "
- + "can't perform updates/deletes");
+ return new OGRFeatureSource(entry, Query.ALL);
}
}
public boolean supportsInPlaceWrite(String typeName) throws IOException {
- // if it's not able to open the datasource in update mode, there's no
- // change it'll be able to support in place write (no need to throw an
- // exception in
- // this case, thus the direct call instead of getOGRDataSource())
- DataSource ds = ogr.OpenShared(ogrSourceName, TRUE);
- if (ds == null)
- return false;
- Layer l = getOGRLayer(ds, typeName);
- boolean retval = l.TestCapability(ogr.OLCDeleteFeature)
- && l.TestCapability(ogr.OLCRandomWrite) && l.TestCapability(ogr.OLCSequentialWrite);
- l.delete();
- ds.delete();
- return retval;
- }
-
- // given up on this one. Some drivers tell you that you can write on a layer
- // only if you opened in update mode. We could try to create a new data
- // source,
- // but unfortunately there is no way to have a generic ogr name that works
- // for every data store. Finally, not all drivers that do write do support
- // datastore deletion. So, in the end, either we can update directly an OGR
- // datasource content, or we have to create a new one and roll our own
- // mechanism to have it replace the old one (this includes moving and
- // deleting
- // the elements that make up a data store).
- public boolean supportsWriteNewLayer(String typeName) throws IOException {
- DataSource ds = getOGRDataSource(FALSE);
- Layer l = getOGRLayer(ds, typeName);
- boolean retval = ds.TestCapability(ogr.ODsCCreateLayer)
- && l.TestCapability(ogr.OLCSequentialWrite);
- l.delete();
- ds.delete();
- return retval;
- }
-
- public ReferencedEnvelope getBounds(Query q) throws IOException {
- if (!q.getFilter().equals(Filter.INCLUDE))
- return null;
-
- DataSource ds = getOGRDataSource(OGRDataStore.FALSE);
- Layer l = getOGRLayer(ds, q.getTypeName());
+ Pointer ds = null;
+ Pointer l = null;
try {
- if (l.TestCapability(ogr.OLCFastGetExtent)) {
- double[] bbox = new double[4];
- // TODO: hum... going thru this forcing the computation is anyways
- // faster than loading all the features just for the sake of
- // getting out the bbox.... but we don't have this
- // explicit middle ground in Geotools
- l.GetExtent(bbox, OGRDataStore.FALSE);
- CoordinateReferenceSystem crs = getSchema(q.getTypeName()).getCoordinateReferenceSystem();
- return new ReferencedEnvelope(bbox[0], bbox[1], bbox[2], bbox[3], crs);
- } else {
- return null;
+ // try opening in update mode
+ ds = OGROpen(pointerToCString(ogrSourceName), 1, null);
+ if (ds == null) {
+ return false;
}
+ l = openOGRLayer(ds, typeName);
+ // for the moment we support working only with random writers
+ boolean canDelete = OGR_L_TestCapability(l, pointerToCString(OLCDeleteFeature)) != 0;
+ boolean canWriteRandom = OGR_L_TestCapability(l, pointerToCString(OLCRandomWrite)) != 0;
+ boolean canWriteSequential = OGR_L_TestCapability(l,
+ pointerToCString(OLCSequentialWrite)) != 0;
+ return canDelete && canWriteRandom && canWriteSequential;
} finally {
- if(l != null)
- l.delete();
- if(ds != null)
- ds.delete();
+ OGRUtils.releaseLayer(l);
+ OGRUtils.releaseDataSource(ds);
}
}
@@ -449,60 +177,33 @@
/**
* Creates a new OGR layer with provided schema and options
*
- * @param schema
- * the geotools schema
- * @param approximateFields
- * if true, OGR will try to create fields that are approximations of the required
- * ones when an exact match cannt be provided
- * @param options
- * OGR data source/layer creation options
+ * @param schema the geotools schema
+ * @param approximateFields if true, OGR will try to create fields that are approximations of
+ * the required ones when an exact match cannt be provided
+ * @param options OGR data source/layer creation options
* @throws IOException
*/
public void createSchema(SimpleFeatureType schema, boolean approximateFields, String[] options)
throws IOException {
- DataSource ds = null;
- Layer l = null;
+ Pointer dataSource = null;
+ Pointer layer = null;
try {
// either open datasource, or try creating one
- Vector optVector = options != null ? new Vector(Arrays.asList(options)) : null;
- try {
- ds = getOGRDataSource(TRUE);
- } catch (IOException e) {
- if (ogrDriverName != null) {
- Driver d = ogr.GetDriverByName(ogrDriverName);
- ds = d.CreateDataSource(ogrSourceName, optVector);
- d.delete();
-
- if (ds == null)
- throw new IOException("Could not create OGR data source with driver "
- + ogrDriverName + " and options " + optVector);
- } else {
- throw new DataSourceException("Driver not provided, and could not "
- + "open data source neither");
- }
+ Pointer<Pointer<Byte>> optionsPointer = null;
+ if (options != null && options.length > 0) {
+ optionsPointer = pointerToCStrings(options);
}
+ dataSource = openOrCreateDataSource(options, dataSource, optionsPointer);
- // get the spatial reference corresponding to the default geometry
- GeometryDescriptor geomType = schema.getGeometryDescriptor();
- int ogrGeomType = getOGRGeometryType(geomType);
- SpatialReference sr = null;
- if (geomType.getCoordinateReferenceSystem() != null) {
- // use tostring to get a lenient wkt translation
- String wkt = geomType.getCoordinateReferenceSystem().toString();
- sr = new SpatialReference(null);
- if (sr.ImportFromWkt(wkt) != 0) {
- sr = null;
- LOGGER.warning("OGR could not parse the geometry WKT," + " detailed error is: "
- + gdal.GetLastErrorMsg() + "\n" + "WKT was: " + wkt);
- }
- }
+ FeatureTypeMapper mapper = new FeatureTypeMapper();
- // create the layer
- l = ds.CreateLayer(schema.getTypeName(), sr, ogrGeomType, optVector);
- if (l == null) {
- throw new DataSourceException("Could not create the OGR layer: "
- + gdal.GetLastErrorMsg());
+ layer = createNewLayer(schema, dataSource, optionsPointer, mapper);
+
+ // check the ability to create fields
+ if (OGR_L_TestCapability(layer, pointerToCString(OLCCreateField)) == 0) {
+ throw new DataSourceException(
+ "OGR reports it's not possible to create fields on this layer");
}
// create fields
@@ -511,211 +212,166 @@
if (ad == schema.getGeometryDescriptor())
continue;
- FieldDefn definition = getOGRFieldDefinition(ad);
- l.CreateField(definition, approximateFields ? TRUE : FALSE);
+ Pointer fieldDefinition = mapper.getOGRFieldDefinition(ad);
+ OGR_L_CreateField(layer, fieldDefinition, approximateFields ? 1 : 0);
}
+
+ OGR_L_SyncToDisk(layer);
} finally {
- if (l != null) {
- l.delete();
- }
- if (ds != null)
- ds.delete();
+ OGRUtils.releaseLayer(layer);
+ OGRUtils.releaseDataSource(dataSource);
}
}
- // ---------------------------------------------------------------------------------------
- // PRIVATE SUPPORT METHODS
- // ---------------------------------------------------------------------------------------
-
- private FieldDefn getOGRFieldDefinition(AttributeDescriptor at) throws IOException {
- final Class type = at.getType().getBinding();
- final FieldDefn def;
- // set type, width, precision and justification where:
- // * width is the number of chars needed to format the strings
- // equivalent of
- // the number
- // * precision is the number of chars after decimal pont
- // * justification: right or left (in outputs)
- // TODO: steal code from Shapefile data store to guess eventual size
- // limitations
- if (Boolean.class.equals(type)) {
- def = new FieldDefn(at.getLocalName(), ogr.OFTString);
- def.SetWidth(5);
- } else if (Byte.class.equals(type)) {
- def = new FieldDefn(at.getLocalName(), ogr.OFTInteger);
- def.SetWidth(3);
- def.SetJustify(ogr.OJRight);
- } else if (Short.class.equals(type)) {
- def = new FieldDefn(at.getLocalName(), ogr.OFTInteger);
- def.SetWidth(5);
- def.SetJustify(ogr.OJRight);
- } else if (Integer.class.equals(type)) {
- def = new FieldDefn(at.getLocalName(), ogr.OFTInteger);
- def.SetWidth(9);
- def.SetJustify(ogr.OJRight);
- } else if (Long.class.equals(type)) {
- def = new FieldDefn(at.getLocalName(), ogr.OFTInteger);
- def.SetWidth(19);
- def.SetJustify(ogr.OJRight);
- } else if (BigInteger.class.equals(type)) {
- def = new FieldDefn(at.getLocalName(), ogr.OFTInteger);
- def.SetWidth(32);
- def.SetJustify(ogr.OJRight);
- } else if (BigDecimal.class.equals(type)) {
- def = new FieldDefn(at.getLocalName(), ogr.OFTReal);
- def.SetWidth(32);
- def.SetPrecision(15);
- def.SetJustify(ogr.OJRight);
- } else if (Float.class.equals(type)) {
- def = new FieldDefn(at.getLocalName(), ogr.OFTReal);
- def.SetWidth(12);
- def.SetPrecision(7);
- def.SetJustify(ogr.OJRight);
- } else if (Double.class.equals(type) || Number.class.isAssignableFrom(type)) {
- def = new FieldDefn(at.getLocalName(), ogr.OFTReal);
- def.SetWidth(22);
- def.SetPrecision(16);
- def.SetJustify(ogr.OJRight);
- } else if (String.class.equals(type)) {
- def = new FieldDefn(at.getLocalName(), ogr.OFTString);
- def.SetWidth(255);
- // TODO: do a serious attempt to cover blob and clob too
- } else if (byte[].class.equals(type)) {
- def = new FieldDefn(at.getLocalName(), ogr.OFTBinary);
- // } else if (java.sql.Date.class.isAssignableFrom(type)) {
- // def = new FieldDefn(at.getLocalName(), ogr.OFTDate);
- // } else if (java.sql.Time.class.isAssignableFrom(type)) {
- // def = new FieldDefn(at.getLocalName(), ogr.OFTTime);
- } else if (java.util.Date.class.isAssignableFrom(type)) {
- def = new FieldDefn(at.getLocalName(), ogr.OFTDateTime);
- } else {
- throw new IOException("Cannot map " + type + " to an OGR type");
- }
-
- return def;
- }
-
/**
- * Tries to open the specified source in either read only or read/write mode
+ * Creates a new OGR layer with provided data and options. This call is specifically made
+ * available for the OGC store since for some data source types, such as GML or KML, it is not
+ * possible to call createSchema() independently from a write, as the result will not contain
+ * the schema definition without having data too. Also, in those formats, the output is writable
+ * only so as long as it's empty, it's not possible to write against an existing GML file for
+ * example.
*
- * @param update
- * open read/write if TRUE, otherwise open read only
- *
- * @return
+ * @param schema the geotools schema
+ * @param approximateFields if true, OGR will try to create fields that are approximations of
+ * the required ones when an exact match cannt be provided
+ * @param options OGR data source/layer creation options
* @throws IOException
*/
- DataSource getOGRDataSource(int update) throws IOException {
- DataSource ds = ogr.OpenShared(ogrSourceName, update);
- if (ds == null)
- throw new IOException("OGR could not open '" + ogrSourceName + "'");
- return ds;
- }
+ public void createSchema(SimpleFeatureCollection data, boolean approximateFields,
+ String[] options) throws IOException {
+ Pointer dataSource = null;
+ Pointer layer = null;
+ SimpleFeatureType schema = data.getSchema();
+ SimpleFeatureIterator features;
+ try {
+ // either open datasource, or try creating one
+ Pointer<Pointer<Byte>> optionsPointer = null;
+ if (options != null && options.length > 0) {
+ optionsPointer = pointer...
[truncated message content] |
|
From: <svn...@os...> - 2012-01-12 07:30:59
|
Author: ang05a
Date: 2012-01-11 23:30:49 -0800 (Wed, 11 Jan 2012)
New Revision: 38479
Added:
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/FilteringMappingFeatureIterator.java
Removed:
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/FilteringMappingFeatureIterator.java
Modified:
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/AbstractMappingFeatureIterator.java
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/AppSchemaDataAccess.java
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/DataAccessMappingFeatureIterator.java
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/FeatureTypeMapping.java
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/MappingAttributeIterator.java
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/MappingFeatureIteratorFactory.java
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/XmlMappingFeatureIterator.java
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/filter/ComplexFilterSplitter.java
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/filter/XPath.java
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/joining/JoiningNestedAttributeMapping.java
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/feature/xpath/XmlAttributeNodePointer.java
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/jdbc/JoiningJDBCFeatureSource.java
trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/FeatureChainingTest.java
trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/PolymorphicChainingTest.java
trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/TimeSeriesTest.java
trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/CGITermValue.properties
trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/CGITermValue.xml
trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/CompositionPart.xml
trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/ControlledConcept.xml
trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/FirstParentFeature.xml
trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/GeologicUnit.properties
trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/GeologicUnit.xml
trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/MappedFeatureAsOccurrence.xml
trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/MappedFeatureMissingNamespaceXlink.xml
trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/PointFeatureGeomPropertyfile.properties
trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/PointFeaturePropertyfile.properties
trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/SecondParentFeature.xml
trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/SimpleContent.properties
trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/exposureColor.properties
Log:
Enable geoserver app-schema-test to run online.
Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/AbstractMappingFeatureIterator.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/AbstractMappingFeatureIterator.java 2012-01-12 04:24:42 UTC (rev 38478)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/AbstractMappingFeatureIterator.java 2012-01-12 07:30:49 UTC (rev 38479)
@@ -20,7 +20,6 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
@@ -30,6 +29,7 @@
import org.geotools.data.complex.filter.XPath.StepList;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.AppSchemaFeatureFactoryImpl;
+import org.geotools.feature.FeatureIterator;
import org.geotools.feature.Types;
import org.geotools.filter.FilterFactoryImplNamespaceAware;
import org.geotools.xlink.XLINK;
@@ -40,7 +40,6 @@
import org.opengis.feature.type.PropertyDescriptor;
import org.opengis.feature.GeometryAttribute;
import org.opengis.feature.Property;
-import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.type.Name;
import org.opengis.filter.FilterFactory;
import org.opengis.filter.FilterFactory2;
@@ -155,7 +154,7 @@
}
xpathAttributeBuilder = new XPath();
xpathAttributeBuilder.setFeatureFactory(attf);
- initialiseSourceFeatures(mapping, unrolledQuery);
+ initialiseSourceFeatures(mapping, unrolledQuery, query.getCoordinateSystemReproject());
xpathAttributeBuilder.setFilterFactory(namespaceAwareFilterFactory);
}
@@ -268,75 +267,24 @@
* @see java.util.Iterator#next()
*/
public Feature next() {
- if (!isHasNextCalled()) {
- LOGGER.warning("hasNext not called before calling next() in the iterator!");
- if (!hasNext()) {
- return null;
- }
+ if (!hasNext()) {
+ throw new IllegalStateException("there are no more features in this iterator");
}
+
Feature next;
try {
next = computeNext();
- this.cleanEmptyElements(next);
} catch (IOException e) {
close();
throw new RuntimeException(e);
}
- ++featureCounter;
+ ++featureCounter;
+
+ setHasNextCalled(false);
return next;
}
- private void cleanEmptyElements(Feature target) throws DataSourceException {
- try {
- ArrayList values = new ArrayList<Property>();
- for (Iterator i = target.getValue().iterator(); i.hasNext();) {
- Property p = (Property) i.next();
-
- if (hasChild(p) || p.getDescriptor().getMinOccurs() > 0) {
- values.add(p);
- }
- }
- target.setValue(values);
- } catch (DataSourceException e) {
- throw new DataSourceException("Unable to clean empty element", e);
- }
- }
-
- private boolean hasChild(Property p) throws DataSourceException {
- boolean result = false;
- if (p.getValue() instanceof Collection) {
-
- Collection c = (Collection) p.getValue();
-
- if (this.getClientProperties(p).containsKey(XLINK_HREF_NAME)) {
- return true;
- }
-
- ArrayList values = new ArrayList();
- for (Object o : c) {
- if (o instanceof Property) {
- if (hasChild((Property) o)) {
- values.add(o);
- result = true;
- } else if (((Property) o).getDescriptor().getMinOccurs() > 0) {
- if (((Property) o).getDescriptor().isNillable()) {
- // add nil mandatory property
- values.add(o);
- }
- }
- }
- }
- p.setValue(values);
- } else if (p.getName().equals(ComplexFeatureConstants.FEATURE_CHAINING_LINK_NAME)) {
- // ignore fake attribute FEATURE_LINK
- result = false;
- } else if (p.getValue() != null && p.getValue().toString().length() > 0) {
- result = true;
- }
- return result;
- }
-
protected Map getClientProperties(Property attribute) throws DataSourceException {
Map<Object, Object> userData = attribute.getUserData();
@@ -439,10 +387,10 @@
protected abstract void closeSourceFeatures();
- protected abstract Iterator<SimpleFeature> getSourceFeatureIterator();
+ protected abstract FeatureIterator<? extends Feature> getSourceFeatureIterator();
- protected abstract void initialiseSourceFeatures(FeatureTypeMapping mapping, Query query)
- throws IOException;
+ protected abstract void initialiseSourceFeatures(FeatureTypeMapping mapping, Query query,
+ CoordinateReferenceSystem crs) throws IOException;
protected abstract boolean unprocessedFeatureExists();
Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/AppSchemaDataAccess.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/AppSchemaDataAccess.java 2012-01-12 04:24:42 UTC (rev 38478)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/AppSchemaDataAccess.java 2012-01-12 07:30:49 UTC (rev 38479)
@@ -306,7 +306,7 @@
@SuppressWarnings("unchecked")
public Query unrollQuery(Query query, FeatureTypeMapping mapping) {
Query unrolledQuery = Query.ALL;
- FeatureSource<FeatureType, Feature> source = mapping.getSource();
+ FeatureSource source = mapping.getSource();
if (!Query.ALL.equals(query)) {
Filter complexFilter = query.getFilter();
@@ -339,8 +339,7 @@
JoiningQuery jQuery = new JoiningQuery(newQuery);
jQuery.setQueryJoins(((JoiningQuery)query).getQueryJoins());
unrolledQuery = jQuery;
- }
- else {
+ } else {
unrolledQuery = newQuery;
}
}
Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/DataAccessMappingFeatureIterator.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/DataAccessMappingFeatureIterator.java 2012-01-12 04:24:42 UTC (rev 38478)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/DataAccessMappingFeatureIterator.java 2012-01-12 07:30:49 UTC (rev 38479)
@@ -31,6 +31,7 @@
import javax.xml.namespace.QName;
import org.geotools.data.DataAccess;
+import org.geotools.data.DataSourceException;
import org.geotools.data.FeatureSource;
import org.geotools.data.Query;
import org.geotools.data.complex.filter.XPath;
@@ -38,7 +39,6 @@
import org.geotools.data.complex.filter.XPath.StepList;
import org.geotools.data.joining.JoiningNestedAttributeMapping;
import org.geotools.data.joining.JoiningQuery;
-import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.AttributeBuilder;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureImpl;
@@ -46,7 +46,6 @@
import org.geotools.feature.Types;
import org.geotools.filter.AttributeExpressionImpl;
import org.geotools.filter.FilterAttributeExtractor;
-import org.geotools.filter.FilterFactoryImpl;
import org.geotools.gml2.bindings.GML2EncodingUtils;
import org.geotools.jdbc.JDBCFeatureSource;
import org.geotools.jdbc.JDBCFeatureStore;
@@ -56,13 +55,10 @@
import org.opengis.feature.ComplexAttribute;
import org.opengis.feature.Feature;
import org.opengis.feature.Property;
-import org.opengis.feature.simple.SimpleFeature;
-import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.AttributeType;
import org.opengis.feature.type.FeatureType;
import org.opengis.feature.type.Name;
-import org.opengis.feature.type.PropertyType;
import org.opengis.filter.expression.Expression;
import org.opengis.filter.expression.PropertyName;
import org.opengis.filter.identity.FeatureId;
@@ -94,7 +90,7 @@
/**
* Hold on to iterator to allow features to be streamed.
*/
- private Iterator<SimpleFeature> sourceFeatureIterator;
+ private FeatureIterator<? extends Feature> sourceFeatureIterator;
/**
* Reprojected CRS from the source simple features, or null
@@ -106,22 +102,34 @@
*/
protected Feature curSrcFeature;
- protected FeatureSource<SimpleFeatureType, SimpleFeature> mappedSource;
+ protected FeatureSource<? extends FeatureType, ? extends Feature> mappedSource;
- protected FeatureCollection<SimpleFeatureType, SimpleFeature> sourceFeatures;
+ protected FeatureCollection<? extends FeatureType, ? extends Feature> sourceFeatures;
protected List<Expression> foreignIds = null;
- private boolean isNextFeatureSet;
-
- private boolean isFiltered;
-
+ /**
+ * True if joining is turned off and pre filter exists. There's a need to run extra query to get
+ * features by id because they might come from denormalised view. The rows might not match the
+ * filter therefore doesn't exist in the mapped source but match the id of other rows.
+ */
+ private boolean isFiltered = false;
+
private ArrayList<String> filteredFeatures;
public DataAccessMappingFeatureIterator(AppSchemaDataAccess store, FeatureTypeMapping mapping,
Query query, boolean isFiltered) throws IOException {
- this(store, mapping, query, isFiltered, null);
+ this(store, mapping, query, null);
+ this.isFiltered = isFiltered;
+ if (isFiltered) {
+ filteredFeatures = new ArrayList<String>();
+ }
}
+
+ public DataAccessMappingFeatureIterator(AppSchemaDataAccess store, FeatureTypeMapping mapping,
+ Query query) throws IOException {
+ this(store, mapping, query, null);
+ }
/**
*
@@ -135,48 +143,37 @@
* @throws IOException
*/
public DataAccessMappingFeatureIterator(AppSchemaDataAccess store, FeatureTypeMapping mapping,
- Query query, boolean isFiltered, Query unrolledQuery) throws IOException {
+ Query query, Query unrolledQuery) throws IOException {
super(store, mapping, query, unrolledQuery);
- this.isFiltered = isFiltered;
- if (isFiltered) {
- filteredFeatures = new ArrayList<String>();
- }
}
@Override
public boolean hasNext() {
- if (isHasNextCalled()) {
- return !isNextSourceFeatureNull();
- }
+ boolean exists = !isNextSourceFeatureNull();
- setHasNextCalled(true);
-
- boolean exists = false;
-
- if (featureCounter < maxFeatures) {
- if (isNextFeatureSet()) {
- flagNextFeature(false);
- return curSrcFeature != null;
- }
-
- if (getSourceFeatureIterator() != null && getSourceFeatureIterator().hasNext()) {
- this.curSrcFeature = getSourceFeatureIterator().next();
- exists = true;
- }
- if (exists && filteredFeatures != null) {
- // get the next one if this row has already been added to the target
- // feature from setNextFilteredFeature
- while (exists && filteredFeatures.contains(extractIdForFeature(this.curSrcFeature))) {
- if (getSourceFeatureIterator() != null && getSourceFeatureIterator().hasNext()) {
- this.curSrcFeature = getSourceFeatureIterator().next();
- exists = true;
- } else {
- exists = false;
+ if (!isHasNextCalled()) {
+ if (featureCounter < maxFeatures) {
+ if (!exists && getSourceFeatureIterator() != null
+ && getSourceFeatureIterator().hasNext()) {
+ this.curSrcFeature = getSourceFeatureIterator().next();
+ exists = true;
+ }
+ if (exists && filteredFeatures != null) {
+ // get the next one if this row has already been added to the target
+ // feature from setNextFilteredFeature
+ while (exists
+ && filteredFeatures.contains(extractIdForFeature(this.curSrcFeature))) {
+ if (getSourceFeatureIterator() != null
+ && getSourceFeatureIterator().hasNext()) {
+ this.curSrcFeature = getSourceFeatureIterator().next();
+ exists = true;
+ } else {
+ exists = false;
+ }
}
}
- if (!exists) {
- curSrcFeature = null;
- }
+ } else {
+ exists = false;
}
}
@@ -186,12 +183,12 @@
curSrcFeature = null;
}
- flagNextFeature(false);
+ setHasNextCalled(true);
return exists;
}
- protected Iterator<SimpleFeature> getSourceFeatureIterator() {
+ protected FeatureIterator<? extends Feature> getSourceFeatureIterator() {
return sourceFeatureIterator;
}
@@ -258,7 +255,7 @@
FilterAttributeExtractor extractor = new FilterAttributeExtractor();
mapping.getFeatureIdExpression().accept(extractor, null);
for (String att : extractor.getAttributeNameSet()) {
- ids.add(peekValue(source, CommonFactoryFinder.getFilterFactory2(null).property( att)));
+ ids.add(peekValue(source, namespaceAwareFilterFactory.property( att)));
}
if (foreignIds != null) {
@@ -275,8 +272,8 @@
return checkForeignIdValues(foreignIdValues, curSrcFeature);
}
- protected void initialiseSourceFeatures(FeatureTypeMapping mapping, Query query)
- throws IOException {
+ protected void initialiseSourceFeatures(FeatureTypeMapping mapping, Query query,
+ CoordinateReferenceSystem targetCRS) throws IOException {
mappedSource = mapping.getSource();
//NC - joining query
@@ -292,7 +289,7 @@
}
String version=(String)this.mapping.getTargetFeature().getType().getUserData().get("targetVersion");
//might be because top level feature has no geometry
- if (query.getCoordinateSystemReproject() == null && version!=null) {
+ if (targetCRS == null && version!=null) {
// figure out the crs the data is in
CoordinateReferenceSystem crs=null;
try{
@@ -317,7 +314,7 @@
this.reprojection = target;
} else {
- this.reprojection = query.getCoordinateSystemReproject();
+ this.reprojection = targetCRS;
}
// we need to disable the max number of features retrieved so we can
@@ -334,7 +331,7 @@
}
}
if (!(this instanceof XmlMappingFeatureIterator)) {
- this.sourceFeatureIterator = sourceFeatures.iterator();
+ this.sourceFeatureIterator = sourceFeatures.features();
}
// NC - joining nested atts
@@ -586,10 +583,9 @@
if (uri != null) {
Attribute instance = xpathAttributeBuilder.set(target, xpath, null, "", targetNodeType,
true, null);
- FilterFactoryImpl ff = new FilterFactoryImpl();
Map<Name, Expression> newClientProps = new HashMap<Name, Expression>();
newClientProps.putAll(clientPropsMappings);
- newClientProps.put(XLINK_HREF_NAME, ff.literal(uri));
+ newClientProps.put(XLINK_HREF_NAME, namespaceAwareFilterFactory.literal(uri));
setClientProperties(instance, null, newClientProps);
}
}
@@ -665,45 +661,46 @@
*/
protected void setXlinkReference(Attribute target, Map<Name, Expression> clientPropsMappings,
Object value, StepList xpath, AttributeType targetNodeType) {
- // Make sure the same value isn't already set
- // in case it comes from a denormalized view for many-to-many relationship.
- // (1) Get the first existing value
- Property existingAttribute = getProperty(target, xpath);
+ Expression linkExpression = clientPropsMappings.get(XLINK_HREF_NAME);
+
+ for (Object singleVal : (Collection) value) {
+ // Make sure the same value isn't already set
+ // in case it comes from a denormalized view for many-to-many relationship.
+ // (1) Get the first existing value
+ Collection<Property> existingAttributes = getProperties((ComplexAttribute) target, xpath);
+ boolean exists = false;
- if (existingAttribute != null) {
- Object existingValue = existingAttribute.getUserData().get(Attributes.class);
- if (existingValue != null) {
- assert existingValue instanceof HashMap;
- existingValue = ((Map) existingValue).get(XLINK_HREF_NAME);
- }
- if (existingValue != null) {
- Expression linkExpression = clientPropsMappings.get(XLINK_HREF_NAME);
- for (Object singleVal : (Collection) value) {
- assert singleVal instanceof Feature;
- assert linkExpression != null;
- Object hrefValue = linkExpression.evaluate(singleVal);
- if (hrefValue != null && hrefValue.equals(existingValue)) {
- // (2) if one of the new values matches the first existing value,
- // that means this comes from a denormalized view,
- // and this set has already been set
- return;
+ if (existingAttributes != null) {
+ for (Property existingAttribute : existingAttributes) {
+ Object existingValue = existingAttribute.getUserData().get(Attributes.class);
+ if (existingValue != null) {
+ assert existingValue instanceof HashMap;
+ existingValue = ((Map) existingValue).get(XLINK_HREF_NAME);
}
+ if (existingValue != null) {
+ Object hrefValue = linkExpression.evaluate(singleVal);
+ if (hrefValue != null && hrefValue.equals(existingValue)) {
+ // (2) if one of the new values matches the first existing value,
+ // that means this comes from a denormalized view,
+ // and this set has already been set
+ exists = true;
+ // stop looking once found
+ break;
+ }
+ }
}
}
+ if (!exists) {
+ Attribute instance = xpathAttributeBuilder.set(target, xpath, null, null,
+ targetNodeType, true, null);
+ setClientProperties(instance, singleVal, clientPropsMappings);
+ }
}
-
- for (Object singleVal : (Collection) value) {
- assert singleVal instanceof Feature;
- Attribute instance = xpathAttributeBuilder.set(target, xpath, null, null,
- targetNodeType, true, null);
- setClientProperties(instance, singleVal, clientPropsMappings);
- }
}
- protected void setNextFeature(String fId, List<Object> foreignIdValues, ArrayList<Feature> features) throws IOException {
- if (features.isEmpty()) {
- features.add(curSrcFeature);
- }
+ protected List<Feature> setNextFeature(String fId, List<Object> foreignIdValues) throws IOException {
+ List<Feature> features = new ArrayList<Feature>();
+ features.add(curSrcFeature);
curSrcFeature = null;
while (getSourceFeatureIterator().hasNext()) {
@@ -712,19 +709,26 @@
features.add(next);
} else {
curSrcFeature = next;
- flagNextFeature(true);
break;
}
}
+ return features;
}
-
- private void setNextFilteredFeature(String fId, ArrayList<Feature> features) throws IOException {
- FeatureCollection<SimpleFeatureType, SimpleFeature> matchingFeatures;
- FeatureId featureId = namespaceAwareFilterFactory.featureId(fId);
+
+ /**
+ * Only used when joining is not used and pre-filter exists because the sources will match
+ * the prefilter but there might be denormalised rows with same id that don't.
+ * @param fId
+ * @param features
+ * @throws IOException
+ */
+ private List<Feature> setNextFilteredFeature(String fId) throws IOException {
+ FeatureCollection<? extends FeatureType, ? extends Feature> matchingFeatures;
Query query = new Query();
if (reprojection != null) {
- if (sourceFeatures.getSchema().getGeometryDescriptor() != null && !this.isReprojectionCrsEqual(this.mappedSource.getSchema()
- .getCoordinateReferenceSystem(),this.reprojection)) {
+ if (sourceFeatures.getSchema().getGeometryDescriptor() != null
+ && !this.isReprojectionCrsEqual(this.mappedSource.getSchema()
+ .getCoordinateReferenceSystem(), this.reprojection)) {
query.setCoordinateSystemReproject(reprojection);
}
}
@@ -733,6 +737,7 @@
// no real feature id mapping,
// so let's find by database row id
Set<FeatureId> ids = new HashSet<FeatureId>();
+ FeatureId featureId = namespaceAwareFilterFactory.featureId(fId);
ids.add(featureId);
query.setFilter(namespaceAwareFilterFactory.id(ids));
matchingFeatures = this.mappedSource.getFeatures(query);
@@ -744,8 +749,9 @@
matchingFeatures = this.mappedSource.getFeatures(query);
}
- FeatureIterator<SimpleFeature> iterator = matchingFeatures.features();
+ FeatureIterator<? extends Feature> iterator = matchingFeatures.features();
+ List<Feature> features = new ArrayList<Feature>();
while (iterator.hasNext()) {
features.add(iterator.next());
}
@@ -757,23 +763,12 @@
filteredFeatures.add(fId);
iterator.close();
-
+
curSrcFeature = null;
+
+ return features;
}
- protected List<Feature> getSources() throws IOException {
- String id = extractIdForFeature(curSrcFeature);
-
- ArrayList<Feature> sources = new ArrayList<Feature>();
- if (isFiltered) {
- setNextFilteredFeature(id, sources);
- } else {
- setNextFeature(id, getForeignIdValues(curSrcFeature), sources);
- }
-
- return sources;
- }
-
public void skipNestedMapping(AttributeMapping attMapping, List<Feature> sources) throws IOException {
if (attMapping instanceof JoiningNestedAttributeMapping) {
@@ -795,7 +790,7 @@
public List<Feature> skip() throws IOException {
setHasNextCalled(false);
- List<Feature> sources = getSources();
+ List<Feature> sources = getSources(extractIdForFeature(curSrcFeature));
for (AttributeMapping attMapping : selectedMapping) {
skipNestedMapping(attMapping, sources);
}
@@ -803,16 +798,10 @@
}
protected Feature computeNext() throws IOException {
- if (curSrcFeature == null) {
- throw new UnsupportedOperationException("No features found in next()."
- + "This wouldn't have happenned if hasNext() was called beforehand.");
- }
- setHasNextCalled(false);
+ String id = getNextFeatureId();
+ List<Feature> sources = getSources(id);
- String id = extractIdForFeature(curSrcFeature);
- List<Feature> sources = getSources();
-
final AttributeDescriptor targetNode = mapping.getTargetFeature();
final Name targetNodeName = targetNode.getName();
@@ -852,9 +841,81 @@
+ attMapping.getTargetXPath(), e);
}
}
+ cleanEmptyElements(target);
+
return target;
}
+ /**
+ * Get all source features of the provided id. This assumes the source features are grouped by
+ * id.
+ *
+ * @param id
+ * The feature id
+ * @return list of source features
+ * @throws IOException
+ */
+ protected List<Feature> getSources(String id) throws IOException {
+ if (isFiltered) {
+ return setNextFilteredFeature(id);
+ } else {
+ return setNextFeature(id, getForeignIdValues(curSrcFeature));
+ }
+ }
+
+ protected String getNextFeatureId() {
+ return extractIdForFeature(curSrcFeature);
+ }
+
+ protected void cleanEmptyElements(Feature target) throws DataSourceException {
+ try {
+ ArrayList values = new ArrayList<Property>();
+ for (Iterator i = target.getValue().iterator(); i.hasNext();) {
+ Property p = (Property) i.next();
+ if (hasChild(p) || p.getDescriptor().getMinOccurs() > 0) {
+ values.add(p);
+ }
+ }
+ target.setValue(values);
+ } catch (DataSourceException e) {
+ throw new DataSourceException("Unable to clean empty element", e);
+ }
+ }
+
+ private boolean hasChild(Property p) throws DataSourceException {
+ boolean result = false;
+ if (p.getValue() instanceof Collection) {
+
+ Collection c = (Collection) p.getValue();
+
+ if (this.getClientProperties(p).containsKey(XLINK_HREF_NAME)) {
+ return true;
+ }
+
+ ArrayList values = new ArrayList();
+ for (Object o : c) {
+ if (o instanceof Property) {
+ if (hasChild((Property) o)) {
+ values.add(o);
+ result = true;
+ } else if (((Property) o).getDescriptor().getMinOccurs() > 0) {
+ if (((Property) o).getDescriptor().isNillable()) {
+ // add nil mandatory property
+ values.add(o);
+ }
+ }
+ }
+ }
+ p.setValue(values);
+ } else if (p.getName().equals(ComplexFeatureConstants.FEATURE_CHAINING_LINK_NAME)) {
+ // ignore fake attribute FEATURE_LINK
+ result = false;
+ } else if (p.getValue() != null && p.getValue().toString().length() > 0) {
+ result = true;
+ }
+ return result;
+ }
+
protected boolean skipTopElement(Name topElement, StepList xpath, AttributeType type) {
// don't skip simple content e.g. when feature chaining gml:name
return Types.equals(topElement, xpath) && !Types.isSimpleContentType(type);
@@ -866,7 +927,7 @@
protected void closeSourceFeatures() {
if (sourceFeatures != null && getSourceFeatureIterator() != null) {
- sourceFeatures.close(sourceFeatureIterator);
+ sourceFeatureIterator.close();
sourceFeatureIterator = null;
sourceFeatures = null;
filteredFeatures = null;
@@ -971,14 +1032,6 @@
return isNested ? (clientPropsMappings.isEmpty() ? false : (clientPropsMappings
.get(XLINK_HREF_NAME) == null) ? false : true) : false;
}
-
- public void flagNextFeature(boolean isSet) {
- this.isNextFeatureSet = isSet;
- }
-
- public boolean isNextFeatureSet() {
- return isNextFeatureSet;
- }
/**
* Returns the declared CRS given the native CRS and the request WFS version
Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/FeatureTypeMapping.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/FeatureTypeMapping.java 2012-01-12 04:24:42 UTC (rev 38478)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/FeatureTypeMapping.java 2012-01-12 07:30:49 UTC (rev 38479)
@@ -30,6 +30,7 @@
import org.geotools.data.complex.filter.XPath;
import org.geotools.data.complex.filter.XPath.Step;
import org.geotools.data.complex.filter.XPath.StepList;
+import org.geotools.data.joining.JoiningNestedAttributeMapping;
import org.geotools.feature.Types;
import org.geotools.filter.NestedAttributeExpression;
import org.geotools.gml3.GML;
@@ -284,23 +285,30 @@
Expression propertyExpression;
for (Iterator it = attributeMappings.iterator(); it.hasNext();) {
attMapping = (AttributeMapping) it.next();
- clientProperties = attMapping.getClientProperties();
- // NC -added
- if (clientPropertyName.equals(GML.id)) {
- clientPropertyExpressions.add(attMapping.getIdentifierExpression());
- } else if (clientProperties.containsKey(clientPropertyName)) {
- // end NC - added
- propertyExpression = (Expression) clientProperties.get(clientPropertyName);
- clientPropertyExpressions.add(propertyExpression);
- } else if (attMapping.isNestedAttribute() && Types.isSimpleContent(parentPath, getTargetFeature().getType())) {
- // create the full xpath from the parent's attribute
- // only bother if this is a simple content
- // otherwise, it would be handled in NestedAttributeExpression since it'd
- // already have the full path then
- StepList fullXpath = parentPath.clone();
- fullXpath.add(new Step(Types.toQName(clientPropertyName, namespaces), 1, true, false));
- clientPropertyExpressions.add(new NestedAttributeExpression(
- fullXpath, this));
+ if (attMapping instanceof JoiningNestedAttributeMapping) {
+ // if it's joining for simple content feature chaining it has to be empty
+ // so it will be added to the post filter
+ clientPropertyExpressions.add(null);
+ } else {
+ clientProperties = attMapping.getClientProperties();
+ // NC -added
+ if (clientPropertyName.equals(GML.id)) {
+ clientPropertyExpressions.add(attMapping.getIdentifierExpression());
+ } else if (clientProperties.containsKey(clientPropertyName)) {
+ // end NC - added
+ propertyExpression = (Expression) clientProperties.get(clientPropertyName);
+ clientPropertyExpressions.add(propertyExpression);
+ } else if (attMapping.isNestedAttribute()
+ && Types.isSimpleContent(parentPath, getTargetFeature().getType())) {
+ // create the full xpath from the parent's attribute
+ // only bother if this is a simple content
+ // otherwise, it would be handled in NestedAttributeExpression since it'd
+ // already have the full path then
+ StepList fullXpath = parentPath.clone();
+ fullXpath.add(new Step(Types.toQName(clientPropertyName, namespaces), 1, true,
+ false));
+ clientPropertyExpressions.add(new NestedAttributeExpression(fullXpath, this));
+ }
}
}
@@ -318,10 +326,13 @@
Expression sourceExpression;
for (Iterator it = attributeMappings.iterator(); it.hasNext();) {
mapping = (AttributeMapping) it.next();
- if (mapping instanceof NestedAttributeMapping) {
+ if (mapping instanceof JoiningNestedAttributeMapping) {
+ // if it's joining for simple content feature chaining it has to be null
+ // so it will be added to the post filter
+ sourceExpression = null;
+ } else if (mapping instanceof NestedAttributeMapping) {
// nested attribute with simple content is possible now
- sourceExpression = new NestedAttributeExpression(
- mapping.getTargetXPath(), this);
+ sourceExpression = new NestedAttributeExpression(mapping.getTargetXPath(), this);
} else {
sourceExpression = mapping.getSourceExpression();
}
Deleted: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/FilteringMappingFeatureIterator.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/FilteringMappingFeatureIterator.java 2012-01-12 04:24:42 UTC (rev 38478)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/FilteringMappingFeatureIterator.java 2012-01-12 07:30:49 UTC (rev 38479)
@@ -1,108 +0,0 @@
-/*
- * GeoTools - The Open Source Java GIS Toolkit
- * http://geotools.org
- *
- * (C) 2010-2011, Open Source Geospatial Foundation (OSGeo)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- */
-
-package org.geotools.data.complex;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.ListIterator;
-
-import org.apache.commons.collections.IteratorUtils;
-import org.geotools.data.Query;
-import org.opengis.feature.Feature;
-import org.opengis.feature.simple.SimpleFeature;
-import org.opengis.filter.Filter;
-
-/**
- * An extension to {@linkplain org.geotools.data.complex.DataAccessMappingFeatureIterator} where
- * filter is present. Since join query between 2 or more tables isn't supported, the only way we can
- * query nested features is by applying the filter per simple feature (database row). This is done
- * in hasNext().
- *
- * @author Rini Angreani (CSIRO Earth Science and Resource Engineering)
- *
- *
- *
- * @source $URL$
- */
-public class FilteringMappingFeatureIterator extends DataAccessMappingFeatureIterator {
-
- protected ListIterator<SimpleFeature> listFeatureIterator;
-
- private Filter filter;
-
- public FilteringMappingFeatureIterator(AppSchemaDataAccess store, FeatureTypeMapping mapping,
- Query query, Query unrolledQuery, Filter filter) throws IOException {
- super(store, mapping, query, false, unrolledQuery);
- this.filter = filter;
- }
-
- @Override
- protected void initialiseSourceFeatures(FeatureTypeMapping mapping, Query query)
- throws IOException {
- super.initialiseSourceFeatures(mapping, query);
- listFeatureIterator = IteratorUtils.toListIterator(super.getSourceFeatureIterator());
- }
-
- @Override
- protected void closeSourceFeatures() {
- super.closeSourceFeatures();
- listFeatureIterator = null;
- }
-
- @Override
- protected ListIterator<SimpleFeature> getSourceFeatureIterator() {
- return listFeatureIterator;
- }
-
- @Override
- public boolean hasNext() {
- // check that the feature exists
- while (super.hasNext()) {
- // apply filter
- if (filter.evaluate(curSrcFeature)) {
- return true;
- }
-
- setHasNextCalled(false);
- }
- return false;
- }
-
- @Override
- protected void setNextFeature(String fId, List<Object> foreignIds, ArrayList<Feature> features) throws IOException {
- int prevCount = 0;
- while (listFeatureIterator.hasPrevious()) {
- Feature prev = listFeatureIterator.previous();
- prevCount++;
- // include other rows that don't match the filter, but matches the id of the
- // matching feature.. for denormalised view
- if (extractIdForFeature(prev).equals(fId)) {
- features.add(prev);
- } else {
- break;
- }
- }
- // get back to the original position
- for (int i = 0; i < prevCount; i++) {
- listFeatureIterator.next();
- }
- // then add next features to same id
- super.setNextFeature(fId, foreignIds, features);
- }
-}
Added: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/FilteringMappingFeatureIterator.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/FilteringMappingFeatureIterator.java (rev 0)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/FilteringMappingFeatureIterator.java 2012-01-12 07:30:49 UTC (rev 38479)
@@ -0,0 +1,171 @@
+/*
+ * GeoTools - The Open Source Java GIS Toolkit
+ * http://geotools.org
+ *
+ * (C) 2010-2011, Open Source Geospatial Foundation (OSGeo)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ */
+
+package org.geotools.data.complex;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.geotools.data.Query;
+import org.geotools.data.store.ReprojectingIterator;
+import org.geotools.factory.FactoryRegistryException;
+import org.geotools.geometry.jts.GeometryCoordinateSequenceTransformer;
+import org.opengis.feature.Feature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.OperationNotFoundException;
+
+/**
+ * An extension to {@linkplain org.geotools.data.complex.DataAccessMappingFeatureIterator} where
+ * filter is present. Since join query between 2 or more tables isn't supported, the only way we can
+ * query nested features is by applying the filter per simple feature (database row). This is done
+ * in hasNext().
+ *
+ * @author Rini Angreani (CSIRO Earth Science and Resource Engineering)
+ *
+ *
+ *
+ * @source $URL$
+ */
+public class FilteringMappingFeatureIterator extends DataAccessMappingFeatureIterator {
+
+ private Filter filter;
+
+ private List<Feature> sources;
+
+ private String currentFeatureId;
+
+ private CoordinateReferenceSystem targetCrs;
+
+ public FilteringMappingFeatureIterator(AppSchemaDataAccess store, FeatureTypeMapping mapping,
+ Query query, Query unrolledQuery, Filter filter) throws IOException {
+ super(store, mapping, query, unrolledQuery);
+ this.filter = filter;
+ // don't reproject if there's no geometry, therefore no source CRS (will cause exception)
+ this.targetCrs = (sourceFeatures.getSchema().getGeometryDescriptor() != null) ? super.reprojection
+ : null;
+ }
+
+ public FilteringMappingFeatureIterator(AppSchemaDataAccess store, FeatureTypeMapping mapping,
+ Query query, Query unrolledQuery, Filter filter, CoordinateReferenceSystem crs)
+ throws IOException {
+ super(store, mapping, query, unrolledQuery);
+ this.filter = filter;
+ this.targetCrs = crs;
+ }
+
+ @Override
+ protected void initialiseSourceFeatures(FeatureTypeMapping mapping, Query query,
+ CoordinateReferenceSystem crs) throws IOException {
+ super.initialiseSourceFeatures(mapping, query, crs);
+ }
+
+ @Override
+ protected void closeSourceFeatures() {
+ super.closeSourceFeatures();
+ this.sources = null;
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (sources != null) {
+ // this is called in the beginning of next()
+ // we don't want to actually check the source iterator again
+ return true;
+ }
+ List<Feature> groupedFeatures;
+ // check that the feature exists
+ boolean matches = false;
+ while (!matches && super.hasNext()) {
+ sources = null;
+ // get all rows with same id from denormalised views
+ // and evaluate each row
+ currentFeatureId = extractIdForFeature(curSrcFeature);
+ try {
+ groupedFeatures = super.getSources(currentFeatureId);
+ Iterator<Feature> srcFeatures = groupedFeatures.iterator();
+ while (!matches && srcFeatures.hasNext()) {
+ // apply filter
+ if (filter == null || filter.evaluate(srcFeatures.next())) {
+ sources = reprojectFeatures(groupedFeatures);
+ matches = true;
+ }
+ }
+ } catch (IOException e) {
+ close();
+ throw new RuntimeException(e);
+ }
+ // reset so next time we call hasNext, it will get the next row
+ setHasNextCalled(false);
+ }
+ return matches;
+ }
+
+ /**
+ * Reproject source features if reprojection is set in the query. This has to be done after filtering, so
+ * it's consistent with JDBCFeatureSource way of filtering and reprojection.
+ * @param srcFeatures
+ * @return
+ * @throws OperationNotFoundException
+ * @throws FactoryRegistryException
+ * @throws FactoryException
+ */
+ @SuppressWarnings("unchecked")
+ private List<Feature> reprojectFeatures(List<Feature> srcFeatures) {
+ if (targetCrs != null) {
+ List<Feature> features = new ArrayList<Feature>();
+ GeometryCoordinateSequenceTransformer transformer = new GeometryCoordinateSequenceTransformer();
+ Iterator<Feature> reprojectedFeatures;
+ try {
+ reprojectedFeatures = new ReprojectingIterator(srcFeatures.iterator(), mappedSource
+ .getSchema().getCoordinateReferenceSystem(), targetCrs,
+ (SimpleFeatureType) this.mappedSource.getSchema(), transformer);
+ while (reprojectedFeatures.hasNext()) {
+ features.add(reprojectedFeatures.next());
+ }
+ } catch (Exception e) {
+ close();
+ throw new RuntimeException ("Failed to reproject features in app-schema!", e);
+ }
+ return features;
+ }
+ return srcFeatures;
+ }
+
+ @Override
+ protected String getNextFeatureId() {
+ return currentFeatureId;
+ }
+
+ @Override
+ protected List<Feature> getSources(String id) throws IOException {
+ // return grouped source features
+ List<Feature> features;
+ if (sources != null) {
+ features = sources;
+ // reset for the next hasNext call
+ sources = null;
+ } else {
+ features = super.getSources(id);
+ }
+ return features;
+ }
+}
Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/MappingAttributeIterator.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/MappingAttributeIterator.java 2012-01-12 04:24:42 UTC (rev 38478)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/MappingAttributeIterator.java 2012-01-12 07:30:49 UTC (rev 38479)
@@ -48,8 +48,8 @@
private Name elementName;
public MappingAttributeIterator(AppSchemaDataAccess store, FeatureTypeMapping mapping,
- Query query, boolean isFiltered, Query unrolledQuery) throws IOException {
- super(store, mapping, query, isFiltered, unrolledQuery);
+ Query query, Query unrolledQuery) throws IOException {
+ super(store, mapping, query, unrolledQuery);
elementName = mapping.getTargetFeature().getName();
checkAttributeMappings();
}
Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/MappingFeatureIteratorFactory.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/MappingFeatureIteratorFactory.java 2012-01-12 04:24:42 UTC (rev 38478)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/MappingFeatureIteratorFactory.java 2012-01-12 07:30:49 UTC (rev 38479)
@@ -34,34 +34,22 @@
import org.geotools.jdbc.JDBCFeatureStore;
import org.opengis.filter.Filter;
import org.opengis.filter.expression.PropertyName;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
/**
* @author Russell Petty (GeoScience Victoria)
- *
- *
- *
- *
- * @source $URL$
+ * @author Rini Angreani (CSIRO Earth Science and Resource Engineering)
+ *
+ * @source $URL:
+ * http://svn.osgeo.org/geotools/trunk/modules/extension/app-schema/app-schema/src/main
+ * /java/org/geotools/data/complex/MappingFeatureIteratorFactory.java $
* http://svn.osgeo.org/geotools/trunk/modules/unsupported/app-schema/app-schema/src/main
* /java/org/geotools/data/complex/MappingFeatureIteratorFactory.java $
*/
public class MappingFeatureIteratorFactory {
protected static final Logger LOGGER = org.geotools.util.logging.Logging
- .getLogger("org.geotools.data.complex");
+ .getLogger("org.geotools.data.complex");
-
- protected static class CheckIfNestedFilterVisitor extends DefaultFilterVisitor {
-
- public boolean hasNestedAttributes = false;
-
- public Object visit( PropertyName expression, Object data ) {
- if (expression instanceof NestedAttributeExpression) {
- hasNestedAttributes = true;
- }
- return data;
- }
- }
-
public static IMappingFeatureIterator getInstance(AppSchemaDataAccess store,
FeatureTypeMapping mapping, Query query, Filter unrolledFilter) throws IOException {
@@ -69,97 +57,107 @@
return new XmlMappingFeatureIterator(store, mapping, query);
}
- if (AppSchemaDataAccessConfigurator.isJoining()) {
+ boolean isJoining = AppSchemaDataAccessConfigurator.isJoining();
+
+ if (isJoining) {
if (!(query instanceof JoiningQuery)) {
query = new JoiningQuery(query);
}
- FeatureSource mappedSource = mapping.getSource();
- FilterCapabilities capabilities = getFilterCapabilities(mappedSource);
-
-
- IMappingFeatureIterator iterator;
- if (unrolledFilter != null) {
- query.setFilter(Filter.INCLUDE);
- Query unrolledQuery = store.unrollQuery(query, mapping);
- unrolledQuery.setFilter(unrolledFilter);
- if (isSimpleType(mapping)) {
- iterator = new MappingAttributeIterator(store, mapping, query, false, unrolledQuery);
- } else {
- iterator = new DataAccessMappingFeatureIterator(store, mapping, query, false, unrolledQuery);
- }
-
+ }
+ IMappingFeatureIterator iterator;
+ if (unrolledFilter != null) {
+ // unrolledFilter is set in JoiningNestedAttributeMapping
+ // so this is for nested features with joining
+ query.setFilter(Filter.INCLUDE);
+ Query unrolledQuery = store.unrollQuery(query, mapping);
+ unrolledQuery.setFilter(unrolledFilter);
+ if (isSimpleType(mapping)) {
+ iterator = new MappingAttributeIterator(store, mapping, query, unrolledQuery);
} else {
+ iterator = new DataAccessMappingFeatureIterator(store, mapping, query,
+ unrolledQuery);
+ }
+ } else {
+ FeatureSource mappedSource = mapping.getSource();
+ if (isJoining || mappedSource instanceof JDBCFeatureSource
+ || mappedSource instanceof JDBCFeatureStore) {
+ // has database as data source, we can use the data source filter capabilities
+ FilterCapabilities capabilities = getFilterCapabilities(mappedSource);
+ ComplexFilterSplitter splitter = new ComplexFilterSplitter(capabilities, mapping);
Filter filter = query.getFilter();
- ComplexFilterSplitter splitter = new ComplexFilterSplitter( capabilities , mapping );
filter.accept(splitter, null);
-
- query.setFilter(splitter.getFilterPre());
+ Filter preFilter = splitter.getFilterPre();
+ query.setFilter(preFilter);
filter = splitter.getFilterPost();
+
int maxFeatures = Query.DEFAULT_MAX;
if (filter != null && filter != Filter.INCLUDE) {
maxFeatures = query.getMaxFeatures();
query.setMaxFeatures(Query.DEFAULT_MAX);
}
- iterator = new DataAccessMappingFeatureIterator(store, mapping, query, false);
+ // need to flag if this is non joining and has pre filter because it needs
+ // to find denormalised rows that match the id (but doesn't match pre filter)
+ boolean isFiltered = !isJoining && preFilter != null && preFilter != Filter.INCLUDE;
+ iterator = new DataAccessMappingFeatureIterator(store, mapping, query, isFiltered);
if (filter != null && filter != Filter.INCLUDE) {
- iterator = new PostFilteringMappingFeatureIterator(iterator, filter, maxFeatures);
+ iterator = new PostFilteringMappingFeatureIterator(iterator, filter,
+ maxFeatures);
}
- }
- return iterator;
- } else {
- if (query.getFilter() != null) {
+ } else if (mappedSource instanceof MappingFeatureSource) {
+ // web service data access wrapper
+ iterator = new DataAccessMappingFeatureIterator(store, mapping, query);
+ } else {
+ // non database sources e.g. property data store
Query unrolledQuery = store.unrollQuery(query, mapping);
Filter filter = unrolledQuery.getFilter();
- CheckIfNestedFilterVisitor visitor = new CheckIfNestedFilterVisitor();
- filter.accept(visitor, null);
- if (visitor.hasNestedAttributes) {
- FeatureSource mappedSource = mapping.getSource();
- if (mappedSource instanceof JDBCFeatureSource
- || mappedSource instanceof JDBCFeatureStore) {
- FilterCapabilities capabilities = getFilterCapabilities(mappedSource);
- ComplexFilterSplitter splitter = new ComplexFilterSplitter(capabilities,
- mapping);
- filter.accept(splitter, null);
- query.setFilter(splitter.getFilterPre());
- unrolledQuery.setFilter(splitter.getFilterPre());
- filter = splitter.getFilterPost();
- } else {
- // VT:no Filtering capbilities cause source may not be of jdbc type
- // therefore we continue;
- // has nested attribute in the filter expression
- unrolledQuery.setFilter(Filter.INCLUDE);
- }
- return new FilteringMappingFeatureIterator(store, mapping, query,
- unrolledQuery, filter);
- } else if (!filter.equals(Filter.INCLUDE) && !filter.equals(Filter.EXCLUDE)
+
+ if (!filter.equals(Filter.INCLUDE) && !filter.equals(Filter.EXCLUDE)
&& !(filter instanceof FidFilterImpl)) {
- // normal filters
- if (isSimpleType(mapping)) {
- return new MappingAttributeIterator(store, mapping, query, true, unrolledQuery);
- } else {
- return new DataAccessMappingFeatureIterator(store, mapping, query, true, unrolledQuery);
+ // non joining with filters
+ // the filter can't be passed to the data source as is and has to be
+ // performed
+ // per simple feature
+ // also in case the data is denormalised and the 2nd row matches the filter, it
+ // will still find the first row
+ // since this iterator would group the sources by id before evaluating the
+ // filter
+ unrolledQuery.setFilter(Filter.INCLUDE);
+
+ CoordinateReferenceSystem crs = query.getCoordinateSystemReproject();
+ if (crs != null) {
+ // remove reprojection too, as it should be done after filter is applied
+ // to be consistent with app-schema with JDBC sources
+ unrolledQuery.setCoordinateSystemReproject(null);
}
+ iterator = new FilteringMappingFeatureIterator(store, mapping, query,
+ unrolledQuery, filter);
+ } else {
+ // non database sources with no filters
+ iterator = new DataAccessMappingFeatureIterator(store, mapping, query);
}
}
-
- return new DataAccessMappingFeatureIterator(store, mapping, query, false);
}
+
+ return iterator;
}
-
+
private static boolean isSimpleType(FeatureTypeMapping mapping) {
- return Types.isSimpleContentType(mapping.getTargetFeature().getType());
+ return Types.isSimpleContentType(mapping.getTargetFeature().getType());
}
-
- private static FilterCapabilities getFilterCapabilities(FeatureSource mappedSource)throws IllegalArgumentException{
- FilterCapabilities capabilities=null;
+
+ private static FilterCapabilities getFilterCapabilities(FeatureSource mappedSource)
+ throws IllegalArgumentException {
+ FilterCapabilities capabilities = null;
if (mappedSource instanceof JDBCFeatureSource) {
- capabilities = ((JDBCFeatureSource) mappedSource).getDataStore().getFilterCapabilities();
- } else if (mappedSource instanceof JDBCFeatureStore){
+ capabilities = ((JDBCFeature...
[truncated message content] |
|
From: <geo...@li...> - 2012-01-12 06:26:29
|
ขบวนการล้มเจ้า ปะทะ ขบวนการล่าแม่มด “ขบวนการล้มเจ้า” เกิดจากการรวมตัวกันอย่างหลวมๆ ของคนที่ต้องการบ่อน ทำลายสถาบันพระมหากษัตริย์ ขณะที่กลุ่มคนที่อยู่ตรงกันข้ามรวมตัวขึ้นต่อต้านเ ป็น “ขบวนการรักเจ้า” แต่ฝ่าย “ขบวนการล้มเจ้า” มองว่าเป็นขบวนการที่จัดตั้งด้วยกลไก ของรัฐ ที่ต้องการทำลายฝ่ายตน และชื่อ “ขบวนการรักเจ้า” ฟังดูดีน่าศรัทธา ทำให้ฝ่าย ตนเสียเปรียบ จึงหาชื่อเรียกขานของฝ่ายตรงข้ามขึ้นมาใหม่ว่า “ขบวนการล่าแม่มด” หรือ “คณะล่าแม่มด” ชื่อนี้มีที่มาอย่างไร... ยุโรปยุคกลาง (Medieval Ages) หรือ ยุคมืด (Dark Ages) เกิดขึ้นหลังจากการล่ม สลายของจักรวรรดิโรมัน ทำให้ยุโรปแตกเป็นอาณาจักรมากมายและไม่มีขื่อแป จนตก เป็นเหยื่อของการรุกรานจากชนชาติภายนอก คริสต์ศาสนาจึงกลายเป็นที่พึ่งและสถาบัน สูงสุดของยุโรป แม้แต่เจ้าเมืองหรือกษัตริย์ก็ต้องฟังคริสตจักร “แม่มด” จึงเป็นแพะรับ บาป ต้องการฆ่าใครทารุนใครก็อ้างว่าเป็นแม่มด การทำลายล้างนั้นถือว่าเป็นความชอบ ธรรม สภาพการณ์ของยุโรปในยุคนั้นจึงเป็นภาพพจน์ของลักษณะความเป็นยุคมืด แล้ว “ขบวนการล่าแม่มด” มันเกี่ยวกับประเทศไทยตรงไหน หรือฝ่าย “ขบวนการล้มเจ้า” มั่วเอาศาสนากับสถาบันกษัตริย์มาปนรวมกันแล้วใช้เป็นข้ออ้าง โจมตีฝ่ายตรงข้าม ประเทศเป็นประชาธิปไตยดีอยู่แล้ว พวก “ขบวนการล้มเจ้า” ที่มี สมาชิกเป็นพวกคอมมิวนิสต์หัวเก่าคงครึ่งหลับครึ่งตื่นอยู่ในภวังค์ก็พยามสร้างกระแส ให้คนไทยมีความรู้สึกว่า พ.ร.บ. การกระทำอันเป็นคอมมิวนิสต์ ที่ถูกยกเลิกไปแล้ว ฟื้น กลับขึ้นมาใหม่ในรูปแบบของ “ขบวนการล่าแม่มด” ใช่ไหม?.... |
|
From: <svn...@os...> - 2012-01-12 04:24:49
|
Author: jive
Date: 2012-01-11 20:24:42 -0800 (Wed, 11 Jan 2012)
New Revision: 38478
Modified:
trunk/docs/src/main/java/org/geotools/api/DataStoreExamples.java
trunk/docs/user/library/api/datastore.rst
trunk/modules/library/api/src/main/java/org/geotools/data/FeatureSource.java
Log:
Update docs to pull in a live code example
Modified: trunk/docs/src/main/java/org/geotools/api/DataStoreExamples.java
===================================================================
--- trunk/docs/src/main/java/org/geotools/api/DataStoreExamples.java 2012-01-12 04:06:03 UTC (rev 38477)
+++ trunk/docs/src/main/java/org/geotools/api/DataStoreExamples.java 2012-01-12 04:24:42 UTC (rev 38478)
@@ -5,12 +5,16 @@
import org.geotools.data.DataStore;
import org.geotools.data.DataUtilities;
+import org.geotools.data.Query;
import org.geotools.data.ServiceInfo;
+import org.geotools.data.simple.SimpleFeatureSource;
+import org.geotools.filter.text.cql2.CQL;
import org.opengis.feature.simple.SimpleFeatureType;
public class DataStoreExamples {
DataStore dataStore = null;
+SimpleFeatureSource featureSource = null;
void exampleInfo() {
// exampleInfo start
@@ -39,4 +43,24 @@
// exampleCreateSchema end
}
+
+void exampleAllCount() throws Exception {
+ // all start
+ int count = featureSource.getCount( Query.ALL );
+ if( count == -1 ){
+ count = featureSource.getFeatures().size();
+ }
+ // all end
}
+
+void exampleQueryCount() throws Exception {
+ // count start
+ Query query = new Query( "typeName", CQL.toFilter("REGION = 3") );
+ int count = featureSource.getCount( query );
+ if( count == -1 ){
+ count = featureSource.getFeatures( query ).size();
+ }
+ // count end
+}
+
+}
Modified: trunk/docs/user/library/api/datastore.rst
===================================================================
--- trunk/docs/user/library/api/datastore.rst 2012-01-12 04:06:03 UTC (rev 38477)
+++ trunk/docs/user/library/api/datastore.rst 2012-01-12 04:24:42 UTC (rev 38478)
@@ -321,21 +321,20 @@
to be very fast. Not all implementations have access to this information making it a bit tricky
to count the number of avaialble features.
- The following code shows how to quickly count all the feautres available::
-
- int count = featureSource.getCount( Query.ALL );
- if( count == -1 ){
- count = featureSource.getFeatures().size();
- }
+ The following code shows how to quickly count all the feautres available:
- You can modify this to use your own Query::
+ .. literalinclude:: /../src/main/java/org/geotools/api/DataStoreExamples.java
+ :language: java
+ :start-after: // all start
+ :end-before: // all end
- Query query = new Query( CQL.toFilter("REGION = 3") );
- int count = featureSource.getCount( query );
- if( count == -1 ){
- count = featureSource.getFeatures( query ).size();
- }
+ You can modify this to use your own Query:
+ .. literalinclude:: /../src/main/java/org/geotools/api/DataStoreExamples.java
+ :language: java
+ :start-after: // count start
+ :end-before: // count end
+
SimpleFeatureStore
''''''''''''''''''
Modified: trunk/modules/library/api/src/main/java/org/geotools/data/FeatureSource.java
===================================================================
--- trunk/modules/library/api/src/main/java/org/geotools/data/FeatureSource.java 2012-01-12 04:06:03 UTC (rev 38477)
+++ trunk/modules/library/api/src/main/java/org/geotools/data/FeatureSource.java 2012-01-12 04:24:42 UTC (rev 38478)
@@ -222,7 +222,7 @@
* <p>
* Example use:<pre><code> int count = featureSource.getCount();
* if( count == -1 ){
- * count = featureSource.getFeatures( count ).size();
+ * count = featureSource.getFeatures( "typeName", count ).size();
* }
*
* @param query the query to select features
|
|
From: <svn...@os...> - 2012-01-12 04:06:10
|
Author: jive Date: 2012-01-11 20:06:03 -0800 (Wed, 11 Jan 2012) New Revision: 38477 Modified: trunk/docs/user/library/api/datastore.rst trunk/modules/library/api/src/main/java/org/geotools/data/FeatureSource.java Log: fix javadoc for FeatureSource getCount and add an example to the docs Modified: trunk/docs/user/library/api/datastore.rst =================================================================== --- trunk/docs/user/library/api/datastore.rst 2012-01-11 15:14:01 UTC (rev 38476) +++ trunk/docs/user/library/api/datastore.rst 2012-01-12 04:06:03 UTC (rev 38477) @@ -13,7 +13,11 @@ References: * :doc:`gt-data <../data/datastore>` DataStore Code Examples +* javadoc: `DataStore <http://docs.geotools.org/latest/javadocs/org/geotools/data/DataStore.html>`_ +* javadoc: `FeatureSource <http://docs.geotools.org/latest/javadocs/org/geotools/data/FeatureSource.html>`_ +* javadoc: `SimpleFeatureSource <http://docs.geotools.org/latest/javadocs/org/geotools/data/simple/SimpleFeatureSource.html>`_ + DataAccess ^^^^^^^^^^ @@ -128,7 +132,6 @@ A FeatureSource is used to provide access to the contents of a DataStore. - .. image:: /images/FeatureSource.PNG **Approach** @@ -169,13 +172,12 @@ // locking supported } - SimpleFeatureSource ''''''''''''''''''' -SimpleFeatueSource is the extension of FeatureSource returned by DataStore to explicitly work with SimpleFeature and SimpleFeatureCollection. +SimpleFeatueSource is the extension of FeatureSource returned by DataStore to explicitly work with +SimpleFeature and SimpleFeatureCollection. - .. image:: /images/SimpleFeatureSource.PNG Access to basic name and schema information: @@ -210,7 +212,14 @@ * FeatureSource.getBounds() * FeatureSource.getBounds(Query) + + May return null if the bounds are unknown or too costly to calculate. + * FeatureSource.getCount(Query) + + May return -1 if the information is not readily avaialble. Formats such as shapefile + keep this information avaialble in the header for handy reference. WFS does not provide + any way to ask for this information and thus always returns -1. Where a request is captured by a **Query**: @@ -304,6 +313,29 @@ query.setHints( new Hints( Query.INCLUDE_MANDITORY_PROPS, Boolean.TRUE ) ); +Examples: + +* How to count the number of features. + + Because the getCount method just checks the file or database header information it is designed + to be very fast. Not all implementations have access to this information making it a bit tricky + to count the number of avaialble features. + + The following code shows how to quickly count all the feautres available:: + + int count = featureSource.getCount( Query.ALL ); + if( count == -1 ){ + count = featureSource.getFeatures().size(); + } + + You can modify this to use your own Query:: + + Query query = new Query( CQL.toFilter("REGION = 3") ); + int count = featureSource.getCount( query ); + if( count == -1 ){ + count = featureSource.getFeatures( query ).size(); + } + SimpleFeatureStore '''''''''''''''''' Modified: trunk/modules/library/api/src/main/java/org/geotools/data/FeatureSource.java =================================================================== --- trunk/modules/library/api/src/main/java/org/geotools/data/FeatureSource.java 2012-01-11 15:14:01 UTC (rev 38476) +++ trunk/modules/library/api/src/main/java/org/geotools/data/FeatureSource.java 2012-01-12 04:06:03 UTC (rev 38477) @@ -217,8 +217,13 @@ * <p> * It is possible that this method will return {@code -1} if the calculation * of number of features is judged to be too costly by the implementing class. - * In this case, you might call <code>getFeatures(query).getBounds()</code> + * In this case, you might call <code>getFeatures(query).size()</code> * instead. + * <p> + * Example use:<pre><code> int count = featureSource.getCount(); + * if( count == -1 ){ + * count = featureSource.getFeatures( count ).size(); + * } * * @param query the query to select features * |
Author: danieleromagnoli
Date: 2012-01-11 07:14:01 -0800 (Wed, 11 Jan 2012)
New Revision: 38476
Modified:
branches/2.7.x/modules/plugin/imageio-ext-gdal/src/main/java/org/geotools/coverageio/RasterLayerRequest.java
branches/2.7.x/modules/plugin/imageio-ext-gdal/src/main/java/org/geotools/coverageio/RasterLayerResponse.java
branches/2.7.x/modules/plugin/jp2k/src/main/java/org/geotools/coverageio/jp2k/Utils.java
branches/2.7.x/pom.xml
Log:
GEOT-3931 Align gt 2.7.x to imageio-ext 1.1.x series
Modified: branches/2.7.x/modules/plugin/imageio-ext-gdal/src/main/java/org/geotools/coverageio/RasterLayerRequest.java
===================================================================
--- branches/2.7.x/modules/plugin/imageio-ext-gdal/src/main/java/org/geotools/coverageio/RasterLayerRequest.java 2012-01-11 05:39:32 UTC (rev 38475)
+++ branches/2.7.x/modules/plugin/imageio-ext-gdal/src/main/java/org/geotools/coverageio/RasterLayerRequest.java 2012-01-11 15:14:01 UTC (rev 38476)
@@ -16,7 +16,7 @@
*/
package org.geotools.coverageio;
-import it.geosolutions.imageio.imageioimpl.imagereadmt.DefaultCloneableImageReadParam;
+import it.geosolutions.imageio.imageioimpl.EnhancedImageReadParam;
import java.awt.Rectangle;
import java.awt.RenderingHints;
@@ -71,6 +71,7 @@
* @author Simone Giannecchini, GeoSolutions
*/
class RasterLayerRequest {
+ static boolean useDestinationRegion = /*Boolean.getBoolean("org.geotools.destination")*/true;
/** Logger. */
private final static Logger LOGGER = org.geotools.util.logging.Logging
@@ -145,7 +146,7 @@
* subsampling factors) which will be used by a coverageResponse to read
* data.
*/
- private ImageReadParam imageReadParam = null;
+ private EnhancedImageReadParam imageReadParam = null;
/** The source */
private Rectangle coverageRequestedRasterArea;
@@ -343,12 +344,8 @@
//
// //
useJAI = requestUsesJaiImageread();
- if (useMultithreading) {
- imageReadParam = new DefaultCloneableImageReadParam();
- } else {
- imageReadParam = new ImageReadParam();
- }
-
+ imageReadParam = new EnhancedImageReadParam();
+
// //
//
// Set the read parameters
@@ -505,28 +502,6 @@
return;
}
- // //
- //
- // Resolution requested. I am here computing the resolution required
- // by the user.
- //
- // //
-// if (requestedEnvelope != null) {
-// final GridToEnvelopeMapper geMapper = new GridToEnvelopeMapper();
-// geMapper.setEnvelope(requestedEnvelope);
-// geMapper.setGridRange(new GridEnvelope2D(requestedDim));
-//
-// // CELL_CORNER comes from GDAL based reader.
-// geMapper.setPixelAnchor(PixelInCell.CELL_CORNER);
-// AffineTransform transform = geMapper.createAffineTransform();
-// requestedRes = CoverageUtilities.getResolution(transform);
-//
-// if (LOGGER.isLoggable(Level.FINE)) {
-// LOGGER.log(Level.FINE, "requested resolution: ("
-// + requestedRes[0] + "," + requestedRes[1] + ")");
-// }
-// }
-
// ////////////////////////////////////////////////////////////////////
//
// DECIMATION ON READING since GDAL will automatically use the
@@ -724,32 +699,26 @@
if (requestedRes == null) {
imageReadParam.setSourceSubsampling(1, 1, 0, 0);
} else {
- int subSamplingFactorX = (int) Math.floor(requestedRes[0]
- / fullResolution[0]);
- subSamplingFactorX = (subSamplingFactorX == 0) ? 1
- : subSamplingFactorX;
+ if (useDestinationRegion && !useJAI){
+ final double xRatio = fullResolution[0]/requestedRes[0];
+ final double yRatio = fullResolution[1]/requestedRes[1];
+ imageReadParam.setDestinationRegion(new Rectangle(0,0,
+ (int)Math.floor(coverageRequestedRasterArea.width*xRatio),
+ (int)Math.floor(coverageRequestedRasterArea.height*yRatio)));
+ } else {
+ int subSamplingFactorX = (int) Math.floor(requestedRes[0] / fullResolution[0]);
+ subSamplingFactorX = (subSamplingFactorX == 0) ? 1 : subSamplingFactorX;
+ while (((w / subSamplingFactorX) <= 0) && (subSamplingFactorX >= 0))
+ subSamplingFactorX--;
+ subSamplingFactorX = (subSamplingFactorX == 0) ? 1 : subSamplingFactorX;
- while (((w / subSamplingFactorX) <= 0)
- && (subSamplingFactorX >= 0))
- subSamplingFactorX--;
-
- subSamplingFactorX = (subSamplingFactorX == 0) ? 1
- : subSamplingFactorX;
-
- int subSamplingFactorY = (int) Math.floor(requestedRes[1]
- / fullResolution[1]);
- subSamplingFactorY = (subSamplingFactorY == 0) ? 1
- : subSamplingFactorY;
-
- while (((h / subSamplingFactorY) <= 0)
- && (subSamplingFactorY >= 0))
- subSamplingFactorY--;
-
- subSamplingFactorY = (subSamplingFactorY == 0) ? 1
- : subSamplingFactorY;
-
- imageReadParam.setSourceSubsampling(subSamplingFactorX,
- subSamplingFactorY, 0, 0);
+ int subSamplingFactorY = (int) Math.floor(requestedRes[1] / fullResolution[1]);
+ subSamplingFactorY = (subSamplingFactorY == 0) ? 1 : subSamplingFactorY;
+ while (((h / subSamplingFactorY) <= 0) && (subSamplingFactorY >= 0))
+ subSamplingFactorY--;
+ subSamplingFactorY = (subSamplingFactorY == 0) ? 1 : subSamplingFactorY;
+ imageReadParam.setSourceSubsampling(subSamplingFactorX, subSamplingFactorY, 0, 0);
+ }
}
}
}
@@ -833,29 +802,6 @@
final GridToEnvelopeMapper geMapper= new GridToEnvelopeMapper(new GridEnvelope2D(requestedRasterArea),requestedBBox);
requestedResolution=CoverageUtilities.getResolution(geMapper.createAffineTransform());
-// ////
-// //
-// // STEP 3: Go back to destination space with the nevelope
-// //
-// ////
-// // transform the intersection envelope from the destination world
-// // space to the requested raster space
-// if (destinationToSourceTransform != null&& !destinationToSourceTransform.isIdentity() )
-// {
-// final GeneralEnvelope temp =CRS.transform(destinationToSourceTransform.inverse(),requestedBBoxInSourceCRS2D) ;
-// temp.setCoordinateReferenceSystem(requestedBBoxCRS2D);
-// requestedBBox = new ReferencedEnvelope(temp);
-//
-// }
-// else
-// //we do not need to do anything
-// requestedBBox=new ReferencedEnvelope(
-// requestedBBoxInSourceCRS2D.getMinX(),
-// requestedBBoxInSourceCRS2D.getMaxX(),
-// requestedBBoxInSourceCRS2D.getMinY(),
-// requestedBBoxInSourceCRS2D.getMaxY(),
-// coverageCRS2D);
-//
return;
} catch (TransformException te) {
Modified: branches/2.7.x/modules/plugin/imageio-ext-gdal/src/main/java/org/geotools/coverageio/RasterLayerResponse.java
===================================================================
--- branches/2.7.x/modules/plugin/imageio-ext-gdal/src/main/java/org/geotools/coverageio/RasterLayerResponse.java 2012-01-11 05:39:32 UTC (rev 38475)
+++ branches/2.7.x/modules/plugin/imageio-ext-gdal/src/main/java/org/geotools/coverageio/RasterLayerResponse.java 2012-01-11 15:14:01 UTC (rev 38476)
@@ -291,9 +291,8 @@
* Returns a {@code PlanarImage} given a set of parameter specifying the
* type of read operation to be performed.
*
- * @param new
- * FileImageInputStreamExtImplinput the input
- * {@code ImageInputStream} to be used for reading the image.
+ * @param input
+ * a File input to be used for reading the image.
* @param useJAI
* {@code true} if we need to use a JAI ImageRead operation,
* {@code false} if we need a simple direct
@@ -311,9 +310,14 @@
final ImageReadParam imageReadParam, final boolean useMultithreading)
throws IOException {
PlanarImage raster;
+ final ImageReader reader;
+ FileImageInputStreamExtImpl fiis = null;
if (useJAI) {
+ fiis = new FileImageInputStreamExtImpl(input);
+ reader = readerSpi.createReaderInstance();
+
final ParameterBlock pbjImageRead = new ParameterBlock();
- pbjImageRead.add(new FileImageInputStreamExtImpl(input));
+ pbjImageRead.add(fiis);
pbjImageRead.add(0);
pbjImageRead.add(Boolean.FALSE);
pbjImageRead.add(Boolean.FALSE);
@@ -321,28 +325,40 @@
pbjImageRead.add(null);
pbjImageRead.add(null);
pbjImageRead.add(imageReadParam);
- pbjImageRead.add(readerSpi.createReaderInstance());
+ pbjImageRead.add(reader);
// Check if to use a simple JAI ImageRead operation or a
// multithreaded one
final String jaiOperation = useMultithreading ? GridCoverageUtilities.IMAGEREADMT: GridCoverageUtilities.IMAGEREAD;
raster = JAI.create(jaiOperation, pbjImageRead, hints);
} else {
- final ImageReader reader = readerSpi.createReaderInstance();
+ reader = readerSpi.createReaderInstance();
+ fiis = new FileImageInputStreamExtImpl(input);
try {
- reader.setInput(new FileImageInputStreamExtImpl(input), true, true);
+ reader.setInput(fiis, true, true);
raster = PlanarImage.wrapRenderedImage(reader.read(0,imageReadParam));
}
finally {
- if(reader!=null)
- try {
- reader.dispose();
- }catch (Exception e) {
- if(LOGGER.isLoggable(Level.FINE))
- LOGGER.log(Level.FINE,e.getLocalizedMessage(),e);
- }
+
+ if (fiis != null) {
+ try {
+ fiis.close();
+ } catch (Exception e) {
+ if (LOGGER.isLoggable(Level.FINE)){
+ LOGGER.log(Level.FINE, e.getLocalizedMessage(), e);
+ }
+ }
+ }
+
+ if (reader != null)
+ try {
+ reader.dispose();
+ } catch (Exception e) {
+ if (LOGGER.isLoggable(Level.FINE)){
+ LOGGER.log(Level.FINE, e.getLocalizedMessage(), e);
+ }
+ }
}
-
}
return raster;
Modified: branches/2.7.x/modules/plugin/jp2k/src/main/java/org/geotools/coverageio/jp2k/Utils.java
===================================================================
--- branches/2.7.x/modules/plugin/jp2k/src/main/java/org/geotools/coverageio/jp2k/Utils.java 2012-01-11 05:39:32 UTC (rev 38475)
+++ branches/2.7.x/modules/plugin/jp2k/src/main/java/org/geotools/coverageio/jp2k/Utils.java 2012-01-11 15:14:01 UTC (rev 38476)
@@ -16,8 +16,7 @@
*/
package org.geotools.coverageio.jp2k;
-import it.geosolutions.imageio.imageioimpl.imagereadmt.CloneableImageReadParam;
-import it.geosolutions.imageio.imageioimpl.imagereadmt.DefaultCloneableImageReadParam;
+import it.geosolutions.imageio.imageioimpl.EnhancedImageReadParam;
import it.geosolutions.imageio.stream.input.FileImageInputStreamExt;
import java.awt.Rectangle;
@@ -161,7 +160,7 @@
// in which there is not a special ImageReadparam used.
// Create a new ImageReadParam instance.
- CloneableImageReadParam newParam = new DefaultCloneableImageReadParam();
+ EnhancedImageReadParam newParam = new EnhancedImageReadParam();
// Set all fields which need to be set.
Modified: branches/2.7.x/pom.xml
===================================================================
--- branches/2.7.x/pom.xml 2012-01-11 05:39:32 UTC (rev 38475)
+++ branches/2.7.x/pom.xml 2012-01-11 15:14:01 UTC (rev 38476)
@@ -73,7 +73,7 @@
<stress.skip.pattern>**/*StressTest.java</stress.skip.pattern>
<test.maxHeapSize>512M</test.maxHeapSize>
<src.output>${basedir}/target</src.output>
- <imageio.ext.version>1.0.8</imageio.ext.version>
+ <imageio.ext.version>1.1.2</imageio.ext.version>
<jt.version>1.1.1</jt.version>
<jvm.opts></jvm.opts>
<maven.build.timestamp.format>dd-MMM-yyyy HH:mm</maven.build.timestamp.format>
|