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
|
Author: aaime
Date: 2012-05-13 13:15:40 -0700 (Sun, 13 May 2012)
New Revision: 38721
Added:
branches/2.7.x/modules/library/coverage/src/test/resources/org/geotools/image/test-data/sf-sfdem.tif.gz
Modified:
branches/2.7.x/modules/library/coverage/src/main/java/org/geotools/image/ImageWorker.java
branches/2.7.x/modules/library/coverage/src/test/java/org/geotools/image/ImageWorkerTest.java
Log:
[GEOT-4144] ImageWorker.writePNG will write out paletted 16bit PNG files (which cannot exist, out of spec)
Modified: branches/2.7.x/modules/library/coverage/src/main/java/org/geotools/image/ImageWorker.java
===================================================================
--- branches/2.7.x/modules/library/coverage/src/main/java/org/geotools/image/ImageWorker.java 2012-05-13 20:13:17 UTC (rev 38720)
+++ branches/2.7.x/modules/library/coverage/src/main/java/org/geotools/image/ImageWorker.java 2012-05-13 20:15:40 UTC (rev 38721)
@@ -2414,9 +2414,20 @@
// we have to reduce colors
forceIndexColorModelForGIF(true);
} else if(!(image.getColorModel() instanceof ComponentColorModel) && !(image.getColorModel() instanceof IndexColorModel)) {
- // png supports gray, rgb, rgba and paletted, but not, for example, double and float values
+ // png supports gray, rgb, rgba and paletted 8 bit, but not, for example, double and float values, or 16 bits palettes
forceComponentColorModel();
}
+
+ // PNG does not support all kinds of index color models
+ if(image.getColorModel() instanceof IndexColorModel) {
+ IndexColorModel icm = (IndexColorModel) image.getColorModel();
+ // PNG supports up to 256 colors, beyond that we have to expand to RGB
+ if(icm.getMapSize() > 256) {
+ forceComponentColorModel(true, true);
+ rescaleToBytes();
+ }
+ }
+
if(LOGGER.isLoggable(Level.FINER))
LOGGER.finer("Encoded input image for png writer");
Modified: branches/2.7.x/modules/library/coverage/src/test/java/org/geotools/image/ImageWorkerTest.java
===================================================================
--- branches/2.7.x/modules/library/coverage/src/test/java/org/geotools/image/ImageWorkerTest.java 2012-05-13 20:13:17 UTC (rev 38720)
+++ branches/2.7.x/modules/library/coverage/src/test/java/org/geotools/image/ImageWorkerTest.java 2012-05-13 20:15:40 UTC (rev 38721)
@@ -16,12 +16,7 @@
*/
package org.geotools.image;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
import java.awt.Color;
import java.awt.Transparency;
@@ -43,6 +38,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Random;
+import java.util.zip.GZIPInputStream;
import javax.imageio.ImageIO;
import javax.media.jai.ImageLayout;
@@ -396,7 +392,65 @@
readWorker.setImage(ImageIO.read(outFile));
assertTrue(readWorker.getRenderedImage().getColorModel() instanceof IndexColorModel);
}
+
+ @Test
+ public void test16BitPNG() throws Exception {
+ // the resource has been compressed since the palette is way larger than the image itself,
+ // and the palette does not get compressed
+ InputStream gzippedStream = ImageWorkerTest.class.getResource("test-data/sf-sfdem.tif.gz").openStream();
+ GZIPInputStream is = new GZIPInputStream(gzippedStream);
+ try {
+ BufferedImage bi = ImageIO.read(is);
+ IndexColorModel icm = (IndexColorModel) bi.getColorModel();
+ assertEquals(65536, icm.getMapSize());
+
+ final File outFile = TestData.temp(this, "temp.png");
+ ImageWorker worker = new ImageWorker(bi);
+ worker.writePNG(outFile, "FILTERED", 0.75f, true, false);
+ worker.dispose();
+
+ // make sure we can read it
+ BufferedImage back = ImageIO.read(outFile);
+
+ // we expect a RGB one
+ ComponentColorModel ccm = (ComponentColorModel) back.getColorModel();
+ assertEquals(3, ccm.getNumColorComponents());
+ } finally {
+ is.close();
+ }
+ }
+
+ /**
+ * Testing TIFF capabilities.
+ *
+ * @throws IOException If an error occured while writting the image.
+ */
+ @Test
+ public void testTIFFWrite() throws IOException {
+ assertTrue("Assertions should be enabled.", ImageWorker.class.desiredAssertionStatus());
+ // Get the image of the world with transparency.
+ final ImageWorker worker = new ImageWorker(worldImage);
+ show(worker, "Input file");
+ // /////////////////////////////////////////////////////////////////////
+ // tiff deflated untiled
+ // /////////////////////////////////////////////////////////////////////
+ final File outFile = TestData.temp(this, "temp.tiff");
+ worker.writeTIFF(outFile, "Deflate", 0.75f, -1, -1);
+ final ImageWorker readWorker = new ImageWorker(ImageIO.read(outFile));
+ show(readWorker, "Tiff untiled");
+
+ // /////////////////////////////////////////////////////////////////////
+ // tiff deflated compressed tiled
+ // /////////////////////////////////////////////////////////////////////
+ worker.setImage(worldImage);
+ worker.writeTIFF(outFile, "Deflate", 0.75f, 32, 32);
+ readWorker.setImage(ImageIO.read(outFile));
+ show(readWorker, "Tiff jpeg compressed, tiled");
+
+ outFile.delete();
+ }
+
/**
* Tests the conversion between RGB and indexed color model.
*/
Added: branches/2.7.x/modules/library/coverage/src/test/resources/org/geotools/image/test-data/sf-sfdem.tif.gz
===================================================================
--- branches/2.7.x/modules/library/coverage/src/test/resources/org/geotools/image/test-data/sf-sfdem.tif.gz (rev 0)
+++ branches/2.7.x/modules/library/coverage/src/test/resources/org/geotools/image/test-data/sf-sfdem.tif.gz 2012-05-13 20:15:40 UTC (rev 38721)
@@ -0,0 +1,55 @@
+ O |
Author: aaime
Date: 2012-05-13 13:13:17 -0700 (Sun, 13 May 2012)
New Revision: 38720
Added:
trunk/modules/library/coverage/src/test/resources/org/geotools/image/test-data/sf-sfdem.tif.gz
Modified:
trunk/modules/library/coverage/src/main/java/org/geotools/image/ImageWorker.java
trunk/modules/library/coverage/src/test/java/org/geotools/image/ImageWorkerTest.java
Log:
[GEOT-4144] ImageWorker.writePNG will write out paletted 16bit PNG files (which cannot exist, out of spec)
Modified: trunk/modules/library/coverage/src/main/java/org/geotools/image/ImageWorker.java
===================================================================
--- trunk/modules/library/coverage/src/main/java/org/geotools/image/ImageWorker.java 2012-05-12 16:50:22 UTC (rev 38719)
+++ trunk/modules/library/coverage/src/main/java/org/geotools/image/ImageWorker.java 2012-05-13 20:13:17 UTC (rev 38720)
@@ -2415,9 +2415,20 @@
// we have to reduce colors
forceIndexColorModelForGIF(true);
} else if(!(image.getColorModel() instanceof ComponentColorModel) && !(image.getColorModel() instanceof IndexColorModel)) {
- // png supports gray, rgb, rgba and paletted, but not, for example, double and float values
+ // png supports gray, rgb, rgba and paletted 8 bit, but not, for example, double and float values, or 16 bits palettes
forceComponentColorModel();
}
+
+ // PNG does not support all kinds of index color models
+ if(image.getColorModel() instanceof IndexColorModel) {
+ IndexColorModel icm = (IndexColorModel) image.getColorModel();
+ // PNG supports up to 256 colors, beyond that we have to expand to RGB
+ if(icm.getMapSize() > 256) {
+ forceComponentColorModel(true, true);
+ rescaleToBytes();
+ }
+ }
+
if(LOGGER.isLoggable(Level.FINER))
LOGGER.finer("Encoded input image for png writer");
Modified: trunk/modules/library/coverage/src/test/java/org/geotools/image/ImageWorkerTest.java
===================================================================
--- trunk/modules/library/coverage/src/test/java/org/geotools/image/ImageWorkerTest.java 2012-05-12 16:50:22 UTC (rev 38719)
+++ trunk/modules/library/coverage/src/test/java/org/geotools/image/ImageWorkerTest.java 2012-05-13 20:13:17 UTC (rev 38720)
@@ -16,12 +16,7 @@
*/
package org.geotools.image;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
import java.awt.Color;
import java.awt.Transparency;
@@ -43,6 +38,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Random;
+import java.util.zip.GZIPInputStream;
import javax.imageio.ImageIO;
import javax.media.jai.ImageLayout;
@@ -398,6 +394,33 @@
assertTrue(readWorker.getRenderedImage().getColorModel() instanceof IndexColorModel);
}
+ @Test
+ public void test16BitPNG() throws Exception {
+ // the resource has been compressed since the palette is way larger than the image itself,
+ // and the palette does not get compressed
+ InputStream gzippedStream = ImageWorkerTest.class.getResource("test-data/sf-sfdem.tif.gz").openStream();
+ GZIPInputStream is = new GZIPInputStream(gzippedStream);
+ try {
+ BufferedImage bi = ImageIO.read(is);
+ IndexColorModel icm = (IndexColorModel) bi.getColorModel();
+ assertEquals(65536, icm.getMapSize());
+
+ final File outFile = TestData.temp(this, "temp.png");
+ ImageWorker worker = new ImageWorker(bi);
+ worker.writePNG(outFile, "FILTERED", 0.75f, true, false);
+ worker.dispose();
+
+ // make sure we can read it
+ BufferedImage back = ImageIO.read(outFile);
+
+ // we expect a RGB one
+ ComponentColorModel ccm = (ComponentColorModel) back.getColorModel();
+ assertEquals(3, ccm.getNumColorComponents());
+ } finally {
+ is.close();
+ }
+ }
+
/**
* Testing TIFF capabilities.
*
Added: trunk/modules/library/coverage/src/test/resources/org/geotools/image/test-data/sf-sfdem.tif.gz
===================================================================
--- trunk/modules/library/coverage/src/test/resources/org/geotools/image/test-data/sf-sfdem.tif.gz (rev 0)
+++ trunk/modules/library/coverage/src/test/resources/org/geotools/image/test-data/sf-sfdem.tif.gz 2012-05-13 20:13:17 UTC (rev 38720)
@@ -0,0 +1,55 @@
+ O |
Author: aaime
Date: 2012-05-12 09:50:22 -0700 (Sat, 12 May 2012)
New Revision: 38719
Added:
branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTest.java
branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTestSetup.java
branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/test/java/org/geotools/data/h2/H2EmptyGeometryTest.java
branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/test/java/org/geotools/data/h2/H2EmptyGeometryTestSetup.java
branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTest.java
branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTestSetup.java
branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/ps/PostGISEmptyGeometryTest.java
Modified:
branches/2.7.x/modules/library/jdbc/src/main/java/org/geotools/jdbc/BasicSQLDialect.java
branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2Dialect.java
branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2DialectBasic.java
branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2DialectPrepared.java
branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISDialect.java
branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISPSDialect.java
branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISTestSetup.java
Log:
[GEOT-4113] Shp publish into postgis datastore with MULTIPOLYGON EMPTY value violates check constraint.
Modified: branches/2.7.x/modules/library/jdbc/src/main/java/org/geotools/jdbc/BasicSQLDialect.java
===================================================================
--- branches/2.7.x/modules/library/jdbc/src/main/java/org/geotools/jdbc/BasicSQLDialect.java 2012-05-12 16:37:03 UTC (rev 38718)
+++ branches/2.7.x/modules/library/jdbc/src/main/java/org/geotools/jdbc/BasicSQLDialect.java 2012-05-12 16:50:22 UTC (rev 38719)
@@ -85,6 +85,10 @@
* The <tt>srid</tt> parameter is the spatial reference system identifier
* of the geometry, or 0 if not known.
* </p>
+ * <p>
+ * Attention should be paid to emtpy geometries (<code>g.isEmtpy() == true</code>) as
+ * they cannot be encoded in WKB and several databases fail to handle them property.
+ * Common treatment is to equate them to NULL</p>
*/
public abstract void encodeGeometryValue(Geometry value, int srid, StringBuffer sql)
throws IOException;
Added: branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTest.java
===================================================================
--- branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTest.java (rev 0)
+++ branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTest.java 2012-05-12 16:50:22 UTC (rev 38719)
@@ -0,0 +1,97 @@
+/*
+ * 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.jdbc;
+
+import org.geotools.data.DefaultTransaction;
+import org.geotools.data.FeatureWriter;
+import org.geotools.data.Transaction;
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureIterator;
+import org.geotools.geometry.jts.JTSFactoryFinder;
+import org.geotools.referencing.CRS;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.io.ParseException;
+import com.vividsolutions.jts.io.WKTReader;
+
+/**
+ *
+ *
+ * @source $URL:
+ * http://svn.osgeo.org/geotools/trunk/modules/library/jdbc/src/test/java/org/geotools/
+ * jdbc/JDBCEmptyGeometryTest.java $
+ */
+public abstract class JDBCEmptyGeometryTest extends JDBCTestSupport {
+
+ @Override
+ protected abstract JDBCEmptyGeometryTestSetup createTestSetup();
+
+ public void testEmptyPoint() throws Exception {
+ testInsertEmptyGeometry("POINT");
+ }
+
+ public void testEmptyLine() throws Exception {
+ testInsertEmptyGeometry("LINESTRING");
+ }
+
+ public void testEmptyPolygon() throws Exception {
+ testInsertEmptyGeometry("POLYGON");
+ }
+
+ public void testEmptyMultiPoint() throws Exception {
+ testInsertEmptyGeometry("MULTIPOINT");
+ }
+
+ public void testEmptyMultiLine() throws Exception {
+ testInsertEmptyGeometry("MULTILINESTRING");
+ }
+
+ public void testEmptyMultiPolygon() throws Exception {
+ testInsertEmptyGeometry("MULTIPOLYGON");
+ }
+
+ private void testInsertEmptyGeometry(String type) throws Exception {
+ WKTReader reader = new WKTReader();
+ Geometry emptyGeometry = reader.read(type.toUpperCase() + " EMPTY");
+
+ Transaction tx = new DefaultTransaction();
+ FeatureWriter<SimpleFeatureType, SimpleFeature> writer = dataStore.getFeatureWriterAppend(
+ tname("empty"), tx);
+ SimpleFeature feature = writer.next();
+ feature.setAttribute(aname("id"), new Integer(100));
+ feature.setAttribute(aname("geom_" + type.toLowerCase()), emptyGeometry);
+ feature.setAttribute(aname("name"), new String("empty " + type));
+ writer.write();
+ writer.close();
+ tx.commit();
+ tx.close();
+
+ SimpleFeatureCollection fc = dataStore.getFeatureSource(tname("empty")).getFeatures();
+ assertEquals(1, fc.size());
+ SimpleFeatureIterator fi = fc.features();
+ SimpleFeature nf = fi.next();
+ fi.close();
+ Geometry geometry = (Geometry) nf.getDefaultGeometry();
+ // either null or empty, we don't really care
+ assertTrue(geometry == null || geometry.isEmpty());
+ }
+}
Added: branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTestSetup.java
===================================================================
--- branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTestSetup.java (rev 0)
+++ branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTestSetup.java 2012-05-12 16:50:22 UTC (rev 38719)
@@ -0,0 +1,50 @@
+/*
+ * 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.jdbc;
+
+import java.sql.SQLException;
+
+/**
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTestSetup.java $
+ */
+public abstract class JDBCEmptyGeometryTestSetup extends JDBCDelegatingTestSetup {
+
+ protected JDBCEmptyGeometryTestSetup(JDBCTestSetup delegate) {
+ super(delegate);
+ }
+
+ protected final void setUpData() throws Exception {
+ //kill all the data
+ try {
+ dropEmptyGeometryTable();
+ } catch (SQLException e) {
+ }
+
+ //create all the data
+ createEmptyGeometryTable();
+ }
+
+ protected abstract void createEmptyGeometryTable() throws Exception;
+
+ /**
+ * Drops the "empty" table previously created
+ */
+ protected abstract void dropEmptyGeometryTable() throws Exception;
+
+}
Modified: branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2Dialect.java
===================================================================
--- branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2Dialect.java 2012-05-12 16:37:03 UTC (rev 38718)
+++ branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2Dialect.java 2012-05-12 16:50:22 UTC (rev 38719)
@@ -340,11 +340,15 @@
public void encodeGeometryValue(Geometry value, int srid, StringBuffer sql)
throws IOException {
- sql.append("ST_GeomFromText ('");
- sql.append(new WKTWriter().write(value));
- sql.append("',");
- sql.append(srid);
- sql.append(")");
+ if(value == null || value.isEmpty()) {
+ sql.append("ST_GeomFromText ('");
+ sql.append(new WKTWriter().write(value));
+ sql.append("',");
+ sql.append(srid);
+ sql.append(")");
+ } else {
+ sql.append("NULL");
+ }
}
Modified: branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2DialectBasic.java
===================================================================
--- branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2DialectBasic.java 2012-05-12 16:37:03 UTC (rev 38718)
+++ branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2DialectBasic.java 2012-05-12 16:50:22 UTC (rev 38719)
@@ -189,7 +189,7 @@
@Override
public void encodeGeometryValue(Geometry value, int srid, StringBuffer sql)
throws IOException {
- if (value != null) {
+ if (value != null && !value.isEmpty()) {
sql.append("ST_GeomFromText ('");
sql.append(new WKTWriter().write(value));
sql.append("',");
Modified: branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2DialectPrepared.java
===================================================================
--- branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2DialectPrepared.java 2012-05-12 16:37:03 UTC (rev 38718)
+++ branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2DialectPrepared.java 2012-05-12 16:50:22 UTC (rev 38719)
@@ -174,7 +174,7 @@
public void setGeometryValue(Geometry g, int srid,
Class binding, PreparedStatement ps, int column)
throws SQLException {
- if ( g == null ) {
+ if ( g == null || g.isEmpty() ) {
ps.setNull( column, Types.BLOB );
return;
}
Added: branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/test/java/org/geotools/data/h2/H2EmptyGeometryTest.java
===================================================================
--- branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/test/java/org/geotools/data/h2/H2EmptyGeometryTest.java (rev 0)
+++ branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/test/java/org/geotools/data/h2/H2EmptyGeometryTest.java 2012-05-12 16:50:22 UTC (rev 38719)
@@ -0,0 +1,34 @@
+/*
+ * 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.h2;
+
+import org.geotools.jdbc.JDBCEmptyGeometryTest;
+import org.geotools.jdbc.JDBCEmptyGeometryTestSetup;
+
+/**
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTest.java $
+ */
+public class H2EmptyGeometryTest extends JDBCEmptyGeometryTest {
+
+ @Override
+ protected JDBCEmptyGeometryTestSetup createTestSetup() {
+ return new H2EmptyGeometryTestSetup(new H2TestSetup());
+ }
+
+}
\ No newline at end of file
Added: branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/test/java/org/geotools/data/h2/H2EmptyGeometryTestSetup.java
===================================================================
--- branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/test/java/org/geotools/data/h2/H2EmptyGeometryTestSetup.java (rev 0)
+++ branches/2.7.x/modules/plugin/jdbc/jdbc-h2/src/test/java/org/geotools/data/h2/H2EmptyGeometryTestSetup.java 2012-05-12 16:50:22 UTC (rev 38719)
@@ -0,0 +1,63 @@
+/*
+ * 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.h2;
+
+import org.geotools.jdbc.JDBCEmptyGeometryTestSetup;
+import org.geotools.jdbc.JDBCTestSetup;
+
+/**
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISBooleanTestSetup.java $
+ */
+public class H2EmptyGeometryTestSetup extends JDBCEmptyGeometryTestSetup {
+
+ public H2EmptyGeometryTestSetup(JDBCTestSetup delegate) {
+ super(delegate);
+ }
+
+ @Override
+ protected void createEmptyGeometryTable() throws Exception {
+ //create table schema
+ run("CREATE TABLE \"geotools\".\"empty\"(" //
+ + "\"fid\" serial primary key, " //
+ + "\"id\" integer, " //
+ + "\"geom_point\" POINT, " //
+ + "\"geom_linestring\" LINESTRING, " //
+ + "\"geom_polygon\" POLYGON, " //
+ + "\"geom_multipoint\" MULTIPOINT, " //
+ + "\"geom_multilinestring\" MULTILINESTRING, " //
+ + "\"geom_multipolygon\" MULTIPOLYGON, " //
+ + "\"name\" varchar" //
+ + ")");
+
+ run("CALL AddGeometryColumn('geotools', 'empty', 'geom_point', 4326, 'POINT', 2)");
+ run("CALL AddGeometryColumn('geotools', 'empty', 'geom_linestring', 4326, 'LINESTRING', 2)");
+ run("CALL AddGeometryColumn('geotools', 'empty', 'geom_polygon', 4326, 'POLYGON', 2)");
+ run("CALL AddGeometryColumn('geotools', 'empty', 'geom_multipoint', 4326, 'MULTIPOINT', 2)");
+ run("CALL AddGeometryColumn('geotools', 'empty', 'geom_multilinestring', 4326, 'MULTILINESTRING', 2)");
+ run("CALL AddGeometryColumn('geotools', 'empty', 'geom_multipolygon', 4326, 'MULTIPOLYGON', 2)");
+ }
+
+ @Override
+ protected void dropEmptyGeometryTable() throws Exception {
+ run( "DROP TABLE \"geotools\".\"empty\"");
+
+ }
+
+
+}
Modified: branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISDialect.java
===================================================================
--- branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISDialect.java 2012-05-12 16:37:03 UTC (rev 38718)
+++ branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISDialect.java 2012-05-12 16:50:22 UTC (rev 38719)
@@ -718,7 +718,7 @@
@Override
public void encodeGeometryValue(Geometry value, int srid, StringBuffer sql)
throws IOException {
- if(value == null) {
+ if (value == null || value.isEmpty()) {
sql.append("NULL");
} else {
if (value instanceof LinearRing) {
Modified: branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISPSDialect.java
===================================================================
--- branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISPSDialect.java 2012-05-12 16:37:03 UTC (rev 38718)
+++ branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISPSDialect.java 2012-05-12 16:50:22 UTC (rev 38719)
@@ -189,7 +189,7 @@
@Override
public void setGeometryValue(Geometry g, int srid, Class binding,
PreparedStatement ps, int column) throws SQLException {
- if (g != null) {
+ if (g != null && !g.isEmpty()) {
if (g instanceof LinearRing ) {
//postgis does not handle linear rings, convert to just a line string
g = g.getFactory().createLineString(((LinearRing) g).getCoordinateSequence());
Added: branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTest.java
===================================================================
--- branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTest.java (rev 0)
+++ branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTest.java 2012-05-12 16:50:22 UTC (rev 38719)
@@ -0,0 +1,34 @@
+/*
+ * 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.postgis;
+
+import org.geotools.jdbc.JDBCEmptyGeometryTest;
+import org.geotools.jdbc.JDBCEmptyGeometryTestSetup;
+
+/**
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTest.java $
+ */
+public class PostGISEmptyGeometryTest extends JDBCEmptyGeometryTest {
+
+ @Override
+ protected JDBCEmptyGeometryTestSetup createTestSetup() {
+ return new PostGISEmptyGeometryTestSetup(new PostGISTestSetup());
+ }
+
+}
\ No newline at end of file
Added: branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTestSetup.java
===================================================================
--- branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTestSetup.java (rev 0)
+++ branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTestSetup.java 2012-05-12 16:50:22 UTC (rev 38719)
@@ -0,0 +1,63 @@
+/*
+ * 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.postgis;
+
+import org.geotools.jdbc.JDBCEmptyGeometryTestSetup;
+import org.geotools.jdbc.JDBCTestSetup;
+
+/**
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISBooleanTestSetup.java $
+ */
+public class PostGISEmptyGeometryTestSetup extends JDBCEmptyGeometryTestSetup {
+
+ public PostGISEmptyGeometryTestSetup(JDBCTestSetup delegate) {
+ super(delegate);
+ }
+
+ @Override
+ protected void createEmptyGeometryTable() throws Exception {
+ //create table schema
+ run("CREATE TABLE \"empty\"(" //
+ + "\"fid\" serial primary key, " //
+ + "\"id\" integer, " //
+ + "\"geom_point\" geometry, " //
+ + "\"geom_linestring\" geometry, " //
+ + "\"geom_polygon\" geometry, " //
+ + "\"geom_multipoint\" geometry, " //
+ + "\"geom_multilinestring\" geometry, " //
+ + "\"geom_multipolygon\" geometry, " //
+ + "\"name\" varchar," //
+ + "CONSTRAINT enforce_geotype_geom_1 CHECK (geometrytype(geom_point) = 'POINT'::text OR geom_point IS NULL)," //
+ + "CONSTRAINT enforce_geotype_geom_2 CHECK (geometrytype(geom_linestring) = 'LINESTRING'::text OR geom_linestring IS NULL)," //
+ + "CONSTRAINT enforce_geotype_geom_3 CHECK (geometrytype(geom_polygon) = 'POLYGON'::text OR geom_polygon IS NULL)," //
+ + "CONSTRAINT enforce_geotype_geom_4 CHECK (geometrytype(geom_multipoint) = 'MULTIPOINT'::text OR geom_multipoint IS NULL)," //
+ + "CONSTRAINT enforce_geotype_geom_5 CHECK (geometrytype(geom_multilinestring) = 'MULTILINESTRING'::text OR geom_multilinestring IS NULL)," //
+ + "CONSTRAINT enforce_geotype_geom_6 CHECK (geometrytype(geom_multipolygon) = 'MULTIPOLYGON'::text OR geom_multipolygon IS NULL)" //
+ + ")");
+
+ }
+
+ @Override
+ protected void dropEmptyGeometryTable() throws Exception {
+ run( "DROP TABLE \"empty\"");
+
+ }
+
+
+}
Modified: branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISTestSetup.java
===================================================================
--- branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISTestSetup.java 2012-05-12 16:37:03 UTC (rev 38718)
+++ branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISTestSetup.java 2012-05-12 16:50:22 UTC (rev 38719)
@@ -69,11 +69,12 @@
run("INSERT INTO \"ft1\" VALUES(0, GeometryFromText('POINT(0 0)', 4326), 0, 0.0, 'zero')");
run("INSERT INTO \"ft1\" VALUES(1, GeometryFromText('POINT(1 1)', 4326), 1, 1.1, 'one')");
run("INSERT INTO \"ft1\" VALUES(2, GeometryFromText('POINT(2 2)', 4326), 2, 2.2, 'two')");
- // advance the sequence to 2
+ // advance the sequence to 2
run("SELECT nextval(pg_get_serial_sequence('ft1','id'))");
run("SELECT nextval(pg_get_serial_sequence('ft1','id'))");
// analyze so that the stats will be up to date
run("ANALYZE \"ft1\"");
+
}
Added: branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/ps/PostGISEmptyGeometryTest.java
===================================================================
--- branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/ps/PostGISEmptyGeometryTest.java (rev 0)
+++ branches/2.7.x/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/ps/PostGISEmptyGeometryTest.java 2012-05-12 16:50:22 UTC (rev 38719)
@@ -0,0 +1,35 @@
+/*
+ * 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.postgis.ps;
+
+import org.geotools.data.postgis.PostGISEmptyGeometryTestSetup;
+import org.geotools.jdbc.JDBCEmptyGeometryTest;
+import org.geotools.jdbc.JDBCEmptyGeometryTestSetup;
+
+/**
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTest.java $
+ */
+public class PostGISEmptyGeometryTest extends JDBCEmptyGeometryTest {
+
+ @Override
+ protected JDBCEmptyGeometryTestSetup createTestSetup() {
+ return new PostGISEmptyGeometryTestSetup(new PostGISPSTestSetup());
+ }
+
+}
\ No newline at end of file
|
Author: aaime
Date: 2012-05-12 09:37:03 -0700 (Sat, 12 May 2012)
New Revision: 38718
Added:
trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTest.java
trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTestSetup.java
trunk/modules/plugin/jdbc/jdbc-h2/src/test/java/org/geotools/data/h2/H2EmptyGeometryTest.java
trunk/modules/plugin/jdbc/jdbc-h2/src/test/java/org/geotools/data/h2/H2EmptyGeometryTestSetup.java
trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTest.java
trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTestSetup.java
trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/ps/PostGISEmptyGeometryTest.java
Modified:
trunk/modules/library/jdbc/src/main/java/org/geotools/jdbc/BasicSQLDialect.java
trunk/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2Dialect.java
trunk/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2DialectBasic.java
trunk/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2DialectPrepared.java
trunk/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISDialect.java
trunk/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISPSDialect.java
trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISTestSetup.java
Log:
[GEOT-4113] Shp publish into postgis datastore with MULTIPOLYGON EMPTY value violates check constraint.
Modified: trunk/modules/library/jdbc/src/main/java/org/geotools/jdbc/BasicSQLDialect.java
===================================================================
--- trunk/modules/library/jdbc/src/main/java/org/geotools/jdbc/BasicSQLDialect.java 2012-05-12 16:10:08 UTC (rev 38717)
+++ trunk/modules/library/jdbc/src/main/java/org/geotools/jdbc/BasicSQLDialect.java 2012-05-12 16:37:03 UTC (rev 38718)
@@ -90,6 +90,10 @@
* The <tt>srid</tt> parameter is the spatial reference system identifier
* of the geometry, or 0 if not known.
* </p>
+ * <p>
+ * Attention should be paid to emtpy geometries (<code>g.isEmtpy() == true</code>) as
+ * they cannot be encoded in WKB and several databases fail to handle them property.
+ * Common treatment is to equate them to NULL</p>
*/
public abstract void encodeGeometryValue(Geometry value, int srid, StringBuffer sql)
throws IOException;
Added: trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTest.java
===================================================================
--- trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTest.java (rev 0)
+++ trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTest.java 2012-05-12 16:37:03 UTC (rev 38718)
@@ -0,0 +1,97 @@
+/*
+ * 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.jdbc;
+
+import org.geotools.data.DefaultTransaction;
+import org.geotools.data.FeatureWriter;
+import org.geotools.data.Transaction;
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureIterator;
+import org.geotools.geometry.jts.JTSFactoryFinder;
+import org.geotools.referencing.CRS;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.io.ParseException;
+import com.vividsolutions.jts.io.WKTReader;
+
+/**
+ *
+ *
+ * @source $URL:
+ * http://svn.osgeo.org/geotools/trunk/modules/library/jdbc/src/test/java/org/geotools/
+ * jdbc/JDBCEmptyGeometryTest.java $
+ */
+public abstract class JDBCEmptyGeometryTest extends JDBCTestSupport {
+
+ @Override
+ protected abstract JDBCEmptyGeometryTestSetup createTestSetup();
+
+ public void testEmptyPoint() throws Exception {
+ testInsertEmptyGeometry("POINT");
+ }
+
+ public void testEmptyLine() throws Exception {
+ testInsertEmptyGeometry("LINESTRING");
+ }
+
+ public void testEmptyPolygon() throws Exception {
+ testInsertEmptyGeometry("POLYGON");
+ }
+
+ public void testEmptyMultiPoint() throws Exception {
+ testInsertEmptyGeometry("MULTIPOINT");
+ }
+
+ public void testEmptyMultiLine() throws Exception {
+ testInsertEmptyGeometry("MULTILINESTRING");
+ }
+
+ public void testEmptyMultiPolygon() throws Exception {
+ testInsertEmptyGeometry("MULTIPOLYGON");
+ }
+
+ private void testInsertEmptyGeometry(String type) throws Exception {
+ WKTReader reader = new WKTReader();
+ Geometry emptyGeometry = reader.read(type.toUpperCase() + " EMPTY");
+
+ Transaction tx = new DefaultTransaction();
+ FeatureWriter<SimpleFeatureType, SimpleFeature> writer = dataStore.getFeatureWriterAppend(
+ tname("empty"), tx);
+ SimpleFeature feature = writer.next();
+ feature.setAttribute(aname("id"), new Integer(100));
+ feature.setAttribute(aname("geom_" + type.toLowerCase()), emptyGeometry);
+ feature.setAttribute(aname("name"), new String("empty " + type));
+ writer.write();
+ writer.close();
+ tx.commit();
+ tx.close();
+
+ SimpleFeatureCollection fc = dataStore.getFeatureSource(tname("empty")).getFeatures();
+ assertEquals(1, fc.size());
+ SimpleFeatureIterator fi = fc.features();
+ SimpleFeature nf = fi.next();
+ fi.close();
+ Geometry geometry = (Geometry) nf.getDefaultGeometry();
+ // either null or empty, we don't really care
+ assertTrue(geometry == null || geometry.isEmpty());
+ }
+}
Added: trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTestSetup.java
===================================================================
--- trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTestSetup.java (rev 0)
+++ trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTestSetup.java 2012-05-12 16:37:03 UTC (rev 38718)
@@ -0,0 +1,50 @@
+/*
+ * 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.jdbc;
+
+import java.sql.SQLException;
+
+/**
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCEmptyGeometryTestSetup.java $
+ */
+public abstract class JDBCEmptyGeometryTestSetup extends JDBCDelegatingTestSetup {
+
+ protected JDBCEmptyGeometryTestSetup(JDBCTestSetup delegate) {
+ super(delegate);
+ }
+
+ protected final void setUpData() throws Exception {
+ //kill all the data
+ try {
+ dropEmptyGeometryTable();
+ } catch (SQLException e) {
+ }
+
+ //create all the data
+ createEmptyGeometryTable();
+ }
+
+ protected abstract void createEmptyGeometryTable() throws Exception;
+
+ /**
+ * Drops the "empty" table previously created
+ */
+ protected abstract void dropEmptyGeometryTable() throws Exception;
+
+}
Modified: trunk/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2Dialect.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2Dialect.java 2012-05-12 16:10:08 UTC (rev 38717)
+++ trunk/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2Dialect.java 2012-05-12 16:37:03 UTC (rev 38718)
@@ -349,11 +349,15 @@
public void encodeGeometryValue(Geometry value, int srid, StringBuffer sql)
throws IOException {
- sql.append("ST_GeomFromText ('");
- sql.append(new WKTWriter().write(value));
- sql.append("',");
- sql.append(srid);
- sql.append(")");
+ if(value == null || value.isEmpty()) {
+ sql.append("ST_GeomFromText ('");
+ sql.append(new WKTWriter().write(value));
+ sql.append("',");
+ sql.append(srid);
+ sql.append(")");
+ } else {
+ sql.append("NULL");
+ }
}
Modified: trunk/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2DialectBasic.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2DialectBasic.java 2012-05-12 16:10:08 UTC (rev 38717)
+++ trunk/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2DialectBasic.java 2012-05-12 16:37:03 UTC (rev 38718)
@@ -190,7 +190,7 @@
@Override
public void encodeGeometryValue(Geometry value, int srid, StringBuffer sql)
throws IOException {
- if (value != null) {
+ if (value != null && !value.isEmpty()) {
sql.append("ST_GeomFromText ('");
sql.append(new WKTWriter().write(value));
sql.append("',");
Modified: trunk/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2DialectPrepared.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2DialectPrepared.java 2012-05-12 16:10:08 UTC (rev 38717)
+++ trunk/modules/plugin/jdbc/jdbc-h2/src/main/java/org/geotools/data/h2/H2DialectPrepared.java 2012-05-12 16:37:03 UTC (rev 38718)
@@ -175,7 +175,7 @@
public void setGeometryValue(Geometry g, int srid,
Class binding, PreparedStatement ps, int column)
throws SQLException {
- if ( g == null ) {
+ if ( g == null || g.isEmpty() ) {
ps.setNull( column, Types.BLOB );
return;
}
Added: trunk/modules/plugin/jdbc/jdbc-h2/src/test/java/org/geotools/data/h2/H2EmptyGeometryTest.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-h2/src/test/java/org/geotools/data/h2/H2EmptyGeometryTest.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-h2/src/test/java/org/geotools/data/h2/H2EmptyGeometryTest.java 2012-05-12 16:37:03 UTC (rev 38718)
@@ -0,0 +1,34 @@
+/*
+ * 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.h2;
+
+import org.geotools.jdbc.JDBCEmptyGeometryTest;
+import org.geotools.jdbc.JDBCEmptyGeometryTestSetup;
+
+/**
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTest.java $
+ */
+public class H2EmptyGeometryTest extends JDBCEmptyGeometryTest {
+
+ @Override
+ protected JDBCEmptyGeometryTestSetup createTestSetup() {
+ return new H2EmptyGeometryTestSetup(new H2TestSetup());
+ }
+
+}
\ No newline at end of file
Added: trunk/modules/plugin/jdbc/jdbc-h2/src/test/java/org/geotools/data/h2/H2EmptyGeometryTestSetup.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-h2/src/test/java/org/geotools/data/h2/H2EmptyGeometryTestSetup.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-h2/src/test/java/org/geotools/data/h2/H2EmptyGeometryTestSetup.java 2012-05-12 16:37:03 UTC (rev 38718)
@@ -0,0 +1,63 @@
+/*
+ * 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.h2;
+
+import org.geotools.jdbc.JDBCEmptyGeometryTestSetup;
+import org.geotools.jdbc.JDBCTestSetup;
+
+/**
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISBooleanTestSetup.java $
+ */
+public class H2EmptyGeometryTestSetup extends JDBCEmptyGeometryTestSetup {
+
+ public H2EmptyGeometryTestSetup(JDBCTestSetup delegate) {
+ super(delegate);
+ }
+
+ @Override
+ protected void createEmptyGeometryTable() throws Exception {
+ //create table schema
+ run("CREATE TABLE \"geotools\".\"empty\"(" //
+ + "\"fid\" serial primary key, " //
+ + "\"id\" integer, " //
+ + "\"geom_point\" POINT, " //
+ + "\"geom_linestring\" LINESTRING, " //
+ + "\"geom_polygon\" POLYGON, " //
+ + "\"geom_multipoint\" MULTIPOINT, " //
+ + "\"geom_multilinestring\" MULTILINESTRING, " //
+ + "\"geom_multipolygon\" MULTIPOLYGON, " //
+ + "\"name\" varchar" //
+ + ")");
+
+ run("CALL AddGeometryColumn('geotools', 'empty', 'geom_point', 4326, 'POINT', 2)");
+ run("CALL AddGeometryColumn('geotools', 'empty', 'geom_linestring', 4326, 'LINESTRING', 2)");
+ run("CALL AddGeometryColumn('geotools', 'empty', 'geom_polygon', 4326, 'POLYGON', 2)");
+ run("CALL AddGeometryColumn('geotools', 'empty', 'geom_multipoint', 4326, 'MULTIPOINT', 2)");
+ run("CALL AddGeometryColumn('geotools', 'empty', 'geom_multilinestring', 4326, 'MULTILINESTRING', 2)");
+ run("CALL AddGeometryColumn('geotools', 'empty', 'geom_multipolygon', 4326, 'MULTIPOLYGON', 2)");
+ }
+
+ @Override
+ protected void dropEmptyGeometryTable() throws Exception {
+ run( "DROP TABLE \"geotools\".\"empty\"");
+
+ }
+
+
+}
Modified: trunk/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISDialect.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISDialect.java 2012-05-12 16:10:08 UTC (rev 38717)
+++ trunk/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISDialect.java 2012-05-12 16:37:03 UTC (rev 38718)
@@ -736,7 +736,7 @@
@Override
public void encodeGeometryValue(Geometry value, int srid, StringBuffer sql)
throws IOException {
- if(value == null) {
+ if (value == null || value.isEmpty()) {
sql.append("NULL");
} else {
if (value instanceof LinearRing) {
Modified: trunk/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISPSDialect.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISPSDialect.java 2012-05-12 16:10:08 UTC (rev 38717)
+++ trunk/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISPSDialect.java 2012-05-12 16:37:03 UTC (rev 38718)
@@ -193,7 +193,7 @@
@Override
public void setGeometryValue(Geometry g, int srid, Class binding,
PreparedStatement ps, int column) throws SQLException {
- if (g != null) {
+ if (g != null && !g.isEmpty()) {
if (g instanceof LinearRing ) {
//postgis does not handle linear rings, convert to just a line string
g = g.getFactory().createLineString(((LinearRing) g).getCoordinateSequence());
Added: trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTest.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTest.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTest.java 2012-05-12 16:37:03 UTC (rev 38718)
@@ -0,0 +1,34 @@
+/*
+ * 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.postgis;
+
+import org.geotools.jdbc.JDBCEmptyGeometryTest;
+import org.geotools.jdbc.JDBCEmptyGeometryTestSetup;
+
+/**
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTest.java $
+ */
+public class PostGISEmptyGeometryTest extends JDBCEmptyGeometryTest {
+
+ @Override
+ protected JDBCEmptyGeometryTestSetup createTestSetup() {
+ return new PostGISEmptyGeometryTestSetup(new PostGISTestSetup());
+ }
+
+}
\ No newline at end of file
Added: trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTestSetup.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTestSetup.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTestSetup.java 2012-05-12 16:37:03 UTC (rev 38718)
@@ -0,0 +1,63 @@
+/*
+ * 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.postgis;
+
+import org.geotools.jdbc.JDBCEmptyGeometryTestSetup;
+import org.geotools.jdbc.JDBCTestSetup;
+
+/**
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISBooleanTestSetup.java $
+ */
+public class PostGISEmptyGeometryTestSetup extends JDBCEmptyGeometryTestSetup {
+
+ public PostGISEmptyGeometryTestSetup(JDBCTestSetup delegate) {
+ super(delegate);
+ }
+
+ @Override
+ protected void createEmptyGeometryTable() throws Exception {
+ //create table schema
+ run("CREATE TABLE \"empty\"(" //
+ + "\"fid\" serial primary key, " //
+ + "\"id\" integer, " //
+ + "\"geom_point\" geometry, " //
+ + "\"geom_linestring\" geometry, " //
+ + "\"geom_polygon\" geometry, " //
+ + "\"geom_multipoint\" geometry, " //
+ + "\"geom_multilinestring\" geometry, " //
+ + "\"geom_multipolygon\" geometry, " //
+ + "\"name\" varchar," //
+ + "CONSTRAINT enforce_geotype_geom_1 CHECK (geometrytype(geom_point) = 'POINT'::text OR geom_point IS NULL)," //
+ + "CONSTRAINT enforce_geotype_geom_2 CHECK (geometrytype(geom_linestring) = 'LINESTRING'::text OR geom_linestring IS NULL)," //
+ + "CONSTRAINT enforce_geotype_geom_3 CHECK (geometrytype(geom_polygon) = 'POLYGON'::text OR geom_polygon IS NULL)," //
+ + "CONSTRAINT enforce_geotype_geom_4 CHECK (geometrytype(geom_multipoint) = 'MULTIPOINT'::text OR geom_multipoint IS NULL)," //
+ + "CONSTRAINT enforce_geotype_geom_5 CHECK (geometrytype(geom_multilinestring) = 'MULTILINESTRING'::text OR geom_multilinestring IS NULL)," //
+ + "CONSTRAINT enforce_geotype_geom_6 CHECK (geometrytype(geom_multipolygon) = 'MULTIPOLYGON'::text OR geom_multipolygon IS NULL)" //
+ + ")");
+
+ }
+
+ @Override
+ protected void dropEmptyGeometryTable() throws Exception {
+ run( "DROP TABLE \"empty\"");
+
+ }
+
+
+}
Modified: trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISTestSetup.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISTestSetup.java 2012-05-12 16:10:08 UTC (rev 38717)
+++ trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISTestSetup.java 2012-05-12 16:37:03 UTC (rev 38718)
@@ -74,11 +74,12 @@
run("INSERT INTO \"ft1\" VALUES(0, GeometryFromText('POINT(0 0)', 4326), 0, 0.0, 'zero')");
run("INSERT INTO \"ft1\" VALUES(1, GeometryFromText('POINT(1 1)', 4326), 1, 1.1, 'one')");
run("INSERT INTO \"ft1\" VALUES(2, GeometryFromText('POINT(2 2)', 4326), 2, 2.2, 'two')");
- // advance the sequence to 2
+ // advance the sequence to 2
run("SELECT nextval(pg_get_serial_sequence('ft1','id'))");
run("SELECT nextval(pg_get_serial_sequence('ft1','id'))");
// analyze so that the stats will be up to date
run("ANALYZE \"ft1\"");
+
}
Added: trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/ps/PostGISEmptyGeometryTest.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/ps/PostGISEmptyGeometryTest.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/ps/PostGISEmptyGeometryTest.java 2012-05-12 16:37:03 UTC (rev 38718)
@@ -0,0 +1,35 @@
+/*
+ * 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.postgis.ps;
+
+import org.geotools.data.postgis.PostGISEmptyGeometryTestSetup;
+import org.geotools.jdbc.JDBCEmptyGeometryTest;
+import org.geotools.jdbc.JDBCEmptyGeometryTestSetup;
+
+/**
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISEmptyGeometryTest.java $
+ */
+public class PostGISEmptyGeometryTest extends JDBCEmptyGeometryTest {
+
+ @Override
+ protected JDBCEmptyGeometryTestSetup createTestSetup() {
+ return new PostGISEmptyGeometryTestSetup(new PostGISPSTestSetup());
+ }
+
+}
\ No newline at end of file
|
|
From: <svn...@os...> - 2012-05-12 16:10:15
|
Author: aaime
Date: 2012-05-12 09:10:08 -0700 (Sat, 12 May 2012)
New Revision: 38717
Modified:
trunk/modules/library/main/src/main/java/org/geotools/data/store/ReprojectingFeatureCollection.java
trunk/modules/library/main/src/test/java/org/geotools/data/store/ReprojectingFeatureCollectionTest.java
Log:
[GEOT-4137] ReprojectingFeatureCollection.getBounds() not returning a ReferencedEnvelope with CRS, patch by Gerson Galang
Modified: trunk/modules/library/main/src/main/java/org/geotools/data/store/ReprojectingFeatureCollection.java
===================================================================
--- trunk/modules/library/main/src/main/java/org/geotools/data/store/ReprojectingFeatureCollection.java 2012-05-12 13:29:31 UTC (rev 38716)
+++ trunk/modules/library/main/src/main/java/org/geotools/data/store/ReprojectingFeatureCollection.java 2012-05-12 16:10:08 UTC (rev 38717)
@@ -241,7 +241,7 @@
newBBox.expandToInclude(internal);
}
}
- return ReferencedEnvelope.reference(newBBox);
+ return new ReferencedEnvelope(newBBox, target);
} catch (Exception e) {
throw new RuntimeException(
"Exception occurred while computing reprojected bounds", e);
Modified: trunk/modules/library/main/src/test/java/org/geotools/data/store/ReprojectingFeatureCollectionTest.java
===================================================================
--- trunk/modules/library/main/src/test/java/org/geotools/data/store/ReprojectingFeatureCollectionTest.java 2012-05-12 13:29:31 UTC (rev 38716)
+++ trunk/modules/library/main/src/test/java/org/geotools/data/store/ReprojectingFeatureCollectionTest.java 2012-05-12 16:10:08 UTC (rev 38717)
@@ -94,7 +94,9 @@
// the reprojection of the full bounds is going to be bigger than the sum of the
// feature by feature reprojected bounds
assertTrue(bounds.transform(target, true).contains((BoundingBox) rfc.getBounds()));
-
+
+ // make sure that the reprojected bounds contain the target CRS
+ assertEquals(target, rfc.getBounds().getCoordinateReferenceSystem());
}
public void testFilter() throws Exception {
|
|
From: <svn...@os...> - 2012-05-12 13:29:39
|
Author: jdeolive
Date: 2012-05-12 06:29:31 -0700 (Sat, 12 May 2012)
New Revision: 38716
Added:
trunk/modules/library/main/src/test/java/org/geotools/xml/ExampleTransformer.java
trunk/modules/library/main/src/test/java/org/geotools/xml/TransformerBaseTest.java
Modified:
trunk/modules/library/main/src/main/java/org/geotools/xml/transform/TransformerBase.java
Log:
GEOT-4125, adding support for mark/reset to TransformerBase to enable buffering writes, patch by David Winslow
Modified: trunk/modules/library/main/src/main/java/org/geotools/xml/transform/TransformerBase.java
===================================================================
--- trunk/modules/library/main/src/main/java/org/geotools/xml/transform/TransformerBase.java 2012-05-12 13:28:17 UTC (rev 38715)
+++ trunk/modules/library/main/src/main/java/org/geotools/xml/transform/TransformerBase.java 2012-05-12 13:29:31 UTC (rev 38716)
@@ -18,8 +18,10 @@
import java.io.StringWriter;
import java.nio.charset.Charset;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -435,7 +437,155 @@
protected final Attributes NULL_ATTS = new AttributesImpl();
protected NamespaceSupport nsSupport = new NamespaceSupport();
protected SchemaLocationSupport schemaLocation;
+
/**
+ * The queue of write operations pending for this translator.
+ * This should be empty if no mark is set.
+ */
+ private List<Action> pending = new ArrayList<Action>();
+
+ /**
+ * An Action records a call to one of the SAX-event-generating methods
+ * on this translator.
+ */
+ private interface Action {
+ void commit();
+ }
+
+ /**
+ * The Start class implements an Action corresponding to starting an
+ * XML element
+ */
+ private class Start implements Action {
+ private final String element;
+ private final Attributes attributes;
+
+ public Start(String element, Attributes attributes) {
+ this.element = element;
+ this.attributes = new AttributesImpl(attributes);
+ }
+
+ public void commit() {
+ _start(element, attributes);
+ }
+ }
+
+ /**
+ * The Chars class implements an Action corresponding to writing a text
+ * block in the XML output
+ */
+ private class Chars implements Action {
+ private final String text;
+
+ public Chars(String text) {
+ this.text = text;
+ }
+
+ public void commit() {
+ _chars(text);
+ }
+ }
+
+ /**
+ * The CData class implements an Action corresponding to writing a
+ * CDATA block in the XML output
+ */
+ private class CData implements Action {
+ private final String text;
+
+ public CData(String text) {
+ this.text = text;
+ }
+
+ public void commit() {
+ _cdata(text);
+ }
+ }
+
+ /**
+ * The End class implements an Action corresponding to closing an XML
+ * element
+ */
+ private class End implements Action {
+ private final String element;
+
+ public End(String element) {
+ this.element = element;
+ }
+
+ public void commit() {
+ _end(element);
+ }
+ }
+
+ /**
+ * The Backend class encapsulates a strategy for writing back to the underlying stream.
+ */
+ private interface Backend {
+ public void start(String element, Attributes attributes);
+ public void chars(String text);
+ public void cdata(String text);
+ public void end(String element);
+ }
+
+ /**
+ * The BufferedBackend queues up write operations in memory, to be committed at a later time.
+ */
+ private class BufferedBackend implements Backend {
+ public void start(String element, Attributes attributes) {
+ pending.add(new Start(element, attributes));
+ }
+
+ public void chars(String text) {
+ pending.add(new Chars(text));
+ }
+
+ public void cdata(String text) {
+ pending.add(new CData(text));
+ }
+
+ public void end(String element) {
+ pending.add(new End(element));
+ }
+ }
+
+ /**
+ * The DirectBackend writes immediately to the underlying output stream.
+ */
+ private class DirectBackend implements Backend {
+ public void start(String element, Attributes attributes) {
+ _start(element, attributes);
+ }
+
+ public void chars(String text) {
+ _chars(text);
+ }
+
+ public void cdata(String text) {
+ _cdata(text);
+ }
+
+ public void end(String element) {
+ _end(element);
+ }
+ }
+
+ /**
+ * A singleton instance of the DirectBackend for this TranslatorSupport instance
+ */
+ private final Backend directBackend = new DirectBackend();
+
+ /**
+ * A singleton instance of the BufferedBackend for this TranslatorSupport instance
+ */
+ private final Backend bufferedBackend = new BufferedBackend();
+
+ /**
+ * The backend currently in use. This should only be modified in the mark/reset/commit methods!
+ */
+ private Backend backend = directBackend;
+
+ /**
* Subclasses should check this flag in case an abort message was sent
* and stop any internal iteration if false.
*/
@@ -455,12 +605,70 @@
this(contentHandler, prefix, nsURI);
this.schemaLocation = schemaLocation;
}
-
+
public void abort() {
running = false;
}
-
+
/**
+ * Set a mark() to which we can later "roll back" writes. After a call
+ * to mark(), the Translator stores pending write operations in memory
+ * until commit() is called. The pending writes can be discarded with
+ * the reset() method.
+ *
+ * Typically, one would use marks in conjunction with an exception handler:
+ *
+ * <pre>
+ * void encodeFoo(Foo f) {
+ * try {
+ * mark();
+ * element(foo.riskyMethod());
+ * element(foo.dangerousMethod());
+ * commit();
+ * } catch (BadThingHappened disaster) {
+ * mitigate(disaster);
+ * reset();
+ * }
+ * }
+ * </pre>
+ *
+ * @throws IllegalStateException if a mark is already set
+ */
+ protected void mark() {
+ if (backend == bufferedBackend) throw new IllegalStateException("Mark already set");
+ backend = bufferedBackend;
+ }
+
+ /**
+ * Discard pending write operations after a mark() has been set.
+ *
+ * This method is safe to call even if no mark is set - so it returns
+ * to a "known good" state as far as marks are concerned.
+ *
+ * @see #mark()
+ */
+ protected void reset() {
+ pending.clear();
+ backend = directBackend;
+ }
+
+ /**
+ * Commit pending write operations. After setting a mark, this method
+ * will commit the pending writes.
+ *
+ * @see #mark()
+ * @throws IllegalStateException if no mark is set
+ */
+ protected void commit() {
+ if (backend != bufferedBackend) throw new IllegalStateException("Can't commit without a mark");
+ for (Action a : pending) {
+ a.commit();
+ }
+ pending.clear();
+ backend = directBackend;
+ }
+
+ /**
* Utility method to copy namespace declarations from "sub" translators
* into this ns support...
*/
@@ -499,7 +707,7 @@
protected void element(String element, String content) {
element(element, content, NULL_ATTS);
}
-
+
/**
* Will only issue the provided element if content is non empty
* @param element
@@ -526,9 +734,12 @@
}
protected void start(String element, Attributes atts) {
+ backend.start(element, atts);
+ }
+
+ private void _start(String element, Attributes atts) {
try {
- String el = (prefix == null) ? element : (prefix + ":"
- + element);
+ String el = (prefix == null) ? element : (prefix + ":" + element);
contentHandler.startElement("", "", el, atts);
} catch (SAXException se) {
throw new RuntimeException(se);
@@ -536,6 +747,10 @@
}
protected void chars(String text) {
+ backend.chars(text);
+ }
+
+ private void _chars(String text) {
try {
char[] ch = text.toCharArray();
contentHandler.characters(ch, 0, ch.length);
@@ -545,6 +760,10 @@
}
protected void end(String element) {
+ backend.end(element);
+ }
+
+ private void _end(String element) {
try {
String el = (prefix == null) ? element : (prefix + ":"
+ element);
@@ -554,13 +773,18 @@
}
}
- protected void cdata( String cdata ) {
- if ( contentHandler instanceof LexicalHandler ) {
+ protected void cdata(String cdata) {
+ backend.cdata(cdata);
+ }
+
+ private void _cdata(String cdata) {
+ if (contentHandler instanceof LexicalHandler) {
LexicalHandler lexicalHandler = (LexicalHandler) contentHandler;
try {
lexicalHandler.startCDATA();
- chars(cdata);
- lexicalHandler.endCDATA();
+ char[] carray = cdata.toCharArray();
+ contentHandler.characters(carray, 0, carray.length);
+ lexicalHandler.endCDATA();
}
catch( SAXException e ) {
throw new RuntimeException( e );
Added: trunk/modules/library/main/src/test/java/org/geotools/xml/ExampleTransformer.java
===================================================================
--- trunk/modules/library/main/src/test/java/org/geotools/xml/ExampleTransformer.java (rev 0)
+++ trunk/modules/library/main/src/test/java/org/geotools/xml/ExampleTransformer.java 2012-05-12 13:29:31 UTC (rev 38716)
@@ -0,0 +1,67 @@
+/*
+ * 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.xml;
+
+import org.geotools.xml.transform.TransformerBase;
+import org.geotools.xml.transform.Translator;
+import org.xml.sax.ContentHandler;
+
+public class ExampleTransformer extends TransformerBase {
+ private final int bufferEveryNth;
+ private final int exceptionEveryNth;
+ private final boolean ignoreErrors;
+
+ public ExampleTransformer(int bufferEveryNth, int exceptionEveryNth, boolean ignoreErrors) {
+ this.bufferEveryNth = bufferEveryNth;
+ this.exceptionEveryNth = exceptionEveryNth;
+ this.ignoreErrors = ignoreErrors;
+ }
+
+ public Translator createTranslator(ContentHandler handler) {
+ return new ExampleTranslator(handler);
+ }
+
+ private class ExampleTranslator extends TranslatorSupport {
+ public ExampleTranslator(ContentHandler handler) {
+ super(handler, "test", "http://geotools.org/test");
+ }
+
+ public void encode(Object o) {
+ Integer i = (Integer)o;
+ start("integers");
+ for (int j = 1; j <= i; j++) {
+ boolean buffer =
+ ((bufferEveryNth != 0) && (j % bufferEveryNth == 0));
+ boolean exception =
+ ((exceptionEveryNth != 0) && (j % exceptionEveryNth == 0));
+
+ try {
+ if (buffer) mark();
+ element("integer", String.valueOf(j));
+ if (exception) throw new RuntimeException();
+ if (buffer) commit();
+ } catch (RuntimeException e) {
+ if (!ignoreErrors) throw e;
+ } finally {
+ reset();
+ }
+ }
+
+ end("integers");
+ }
+ }
+}
Added: trunk/modules/library/main/src/test/java/org/geotools/xml/TransformerBaseTest.java
===================================================================
--- trunk/modules/library/main/src/test/java/org/geotools/xml/TransformerBaseTest.java (rev 0)
+++ trunk/modules/library/main/src/test/java/org/geotools/xml/TransformerBaseTest.java 2012-05-12 13:29:31 UTC (rev 38716)
@@ -0,0 +1,85 @@
+/*
+ * 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.xml;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import javax.xml.transform.TransformerException;
+
+import junit.framework.TestCase;
+
+public class TransformerBaseTest extends TestCase {
+
+ public void testUnbufferedUsageNoErrors() throws FileNotFoundException, TransformerException {
+ String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test:integers xmlns=\"http://geotools.org/test\" xmlns:test=\"http://geotools.org/test\"><test:integer>1</test:integer><test:integer>2</test:integer><test:integer>3</test:integer><test:integer>4</test:integer><test:integer>5</test:integer><test:integer>6</test:integer><test:integer>7</test:integer><test:integer>8</test:integer><test:integer>9</test:integer><test:integer>10</test:integer></test:integers>";
+ ExampleTransformer tx = new ExampleTransformer(0, 0, false);
+ String actual = tx.transform(10);
+ assertEquals(expected, actual);
+ }
+
+ public void testUnbufferedUsageOneError() throws FileNotFoundException, TransformerException {
+ StringWriter w = new StringWriter();
+ try {
+ ExampleTransformer tx = new ExampleTransformer(0, 10, false);
+ tx.transform(10, w);
+ fail("Should have thrown an exception before reaching this point");
+ } catch (TransformerException e) {
+ String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test:integers xmlns=\"http://geotools.org/test\" xmlns:test=\"http://geotools.org/test\"><test:integer>1</test:integer><test:integer>2</test:integer><test:integer>3</test:integer><test:integer>4</test:integer><test:integer>5</test:integer><test:integer>6</test:integer><test:integer>7</test:integer><test:integer>8</test:integer><test:integer>9</test:integer><test:integer>10</test:integer>";
+ String actual = w.toString();
+ assertEquals(expected, actual);
+ }
+ }
+
+ public void testBufferedUsageNoErrors() throws FileNotFoundException, TransformerException {
+ String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test:integers xmlns=\"http://geotools.org/test\" xmlns:test=\"http://geotools.org/test\"><test:integer>1</test:integer><test:integer>2</test:integer><test:integer>3</test:integer><test:integer>4</test:integer><test:integer>5</test:integer><test:integer>6</test:integer><test:integer>7</test:integer><test:integer>8</test:integer><test:integer>9</test:integer><test:integer>10</test:integer></test:integers>";
+ ExampleTransformer tx = new ExampleTransformer(1, 0, false);
+ String actual = tx.transform(10);
+ assertEquals(expected, actual);
+ }
+
+ public void testBufferedUsageOneError() throws FileNotFoundException, TransformerException {
+ StringWriter w = new StringWriter();
+ try {
+ ExampleTransformer tx = new ExampleTransformer(1, 10, false);
+ tx.transform(10, w);
+ fail("Should have thrown an exception before reaching this point!");
+ } catch (TransformerException e) {
+ String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test:integers xmlns=\"http://geotools.org/test\" xmlns:test=\"http://geotools.org/test\"><test:integer>1</test:integer><test:integer>2</test:integer><test:integer>3</test:integer><test:integer>4</test:integer><test:integer>5</test:integer><test:integer>6</test:integer><test:integer>7</test:integer><test:integer>8</test:integer><test:integer>9</test:integer>";
+ String actual = w.toString();
+ assertEquals(expected, actual);
+ }
+ }
+
+ public void testBufferedUsageIgnoringOneError() throws FileNotFoundException, TransformerException {
+ ExampleTransformer tx = new ExampleTransformer(1, 10, true);
+ String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test:integers xmlns=\"http://geotools.org/test\" xmlns:test=\"http://geotools.org/test\"><test:integer>1</test:integer><test:integer>2</test:integer><test:integer>3</test:integer><test:integer>4</test:integer><test:integer>5</test:integer><test:integer>6</test:integer><test:integer>7</test:integer><test:integer>8</test:integer><test:integer>9</test:integer></test:integers>";
+ String actual = tx.transform(10);
+ assertEquals(expected, actual);
+ }
+
+ public void testBufferedUsageIgnoringMultipleErrors() throws FileNotFoundException, TransformerException {
+ ExampleTransformer tx = new ExampleTransformer(1, 2, true);
+ String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test:integers xmlns=\"http://geotools.org/test\" xmlns:test=\"http://geotools.org/test\"><test:integer>1</test:integer><test:integer>3</test:integer><test:integer>5</test:integer><test:integer>7</test:integer><test:integer>9</test:integer></test:integers>";
+ String actual = tx.transform(10);
+ assertEquals(expected, actual);
+ }
+}
|
|
From: <svn...@os...> - 2012-05-12 13:28:25
|
Author: jdeolive
Date: 2012-05-12 06:28:17 -0700 (Sat, 12 May 2012)
New Revision: 38715
Added:
branches/2.7.x/modules/library/main/src/test/java/org/geotools/xml/ExampleTransformer.java
branches/2.7.x/modules/library/main/src/test/java/org/geotools/xml/TransformerBaseTest.java
Modified:
branches/2.7.x/modules/library/main/src/main/java/org/geotools/xml/transform/TransformerBase.java
Log:
GEOT-4125, adding support for mark/reset to TransformerBase to enable buffering writes, patch by David Winslow
Modified: branches/2.7.x/modules/library/main/src/main/java/org/geotools/xml/transform/TransformerBase.java
===================================================================
--- branches/2.7.x/modules/library/main/src/main/java/org/geotools/xml/transform/TransformerBase.java 2012-05-11 23:03:22 UTC (rev 38714)
+++ branches/2.7.x/modules/library/main/src/main/java/org/geotools/xml/transform/TransformerBase.java 2012-05-12 13:28:17 UTC (rev 38715)
@@ -18,8 +18,10 @@
import java.io.StringWriter;
import java.nio.charset.Charset;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -434,7 +436,155 @@
protected final Attributes NULL_ATTS = new AttributesImpl();
protected NamespaceSupport nsSupport = new NamespaceSupport();
protected SchemaLocationSupport schemaLocation;
+
/**
+ * The queue of write operations pending for this translator.
+ * This should be empty if no mark is set.
+ */
+ private List<Action> pending = new ArrayList<Action>();
+
+ /**
+ * An Action records a call to one of the SAX-event-generating methods
+ * on this translator.
+ */
+ private interface Action {
+ void commit();
+ }
+
+ /**
+ * The Start class implements an Action corresponding to starting an
+ * XML element
+ */
+ private class Start implements Action {
+ private final String element;
+ private final Attributes attributes;
+
+ public Start(String element, Attributes attributes) {
+ this.element = element;
+ this.attributes = new AttributesImpl(attributes);
+ }
+
+ public void commit() {
+ _start(element, attributes);
+ }
+ }
+
+ /**
+ * The Chars class implements an Action corresponding to writing a text
+ * block in the XML output
+ */
+ private class Chars implements Action {
+ private final String text;
+
+ public Chars(String text) {
+ this.text = text;
+ }
+
+ public void commit() {
+ _chars(text);
+ }
+ }
+
+ /**
+ * The CData class implements an Action corresponding to writing a
+ * CDATA block in the XML output
+ */
+ private class CData implements Action {
+ private final String text;
+
+ public CData(String text) {
+ this.text = text;
+ }
+
+ public void commit() {
+ _cdata(text);
+ }
+ }
+
+ /**
+ * The End class implements an Action corresponding to closing an XML
+ * element
+ */
+ private class End implements Action {
+ private final String element;
+
+ public End(String element) {
+ this.element = element;
+ }
+
+ public void commit() {
+ _end(element);
+ }
+ }
+
+ /**
+ * The Backend class encapsulates a strategy for writing back to the underlying stream.
+ */
+ private interface Backend {
+ public void start(String element, Attributes attributes);
+ public void chars(String text);
+ public void cdata(String text);
+ public void end(String element);
+ }
+
+ /**
+ * The BufferedBackend queues up write operations in memory, to be committed at a later time.
+ */
+ private class BufferedBackend implements Backend {
+ public void start(String element, Attributes attributes) {
+ pending.add(new Start(element, attributes));
+ }
+
+ public void chars(String text) {
+ pending.add(new Chars(text));
+ }
+
+ public void cdata(String text) {
+ pending.add(new CData(text));
+ }
+
+ public void end(String element) {
+ pending.add(new End(element));
+ }
+ }
+
+ /**
+ * The DirectBackend writes immediately to the underlying output stream.
+ */
+ private class DirectBackend implements Backend {
+ public void start(String element, Attributes attributes) {
+ _start(element, attributes);
+ }
+
+ public void chars(String text) {
+ _chars(text);
+ }
+
+ public void cdata(String text) {
+ _cdata(text);
+ }
+
+ public void end(String element) {
+ _end(element);
+ }
+ }
+
+ /**
+ * A singleton instance of the DirectBackend for this TranslatorSupport instance
+ */
+ private final Backend directBackend = new DirectBackend();
+
+ /**
+ * A singleton instance of the BufferedBackend for this TranslatorSupport instance
+ */
+ private final Backend bufferedBackend = new BufferedBackend();
+
+ /**
+ * The backend currently in use. This should only be modified in the mark/reset/commit methods!
+ */
+ private Backend backend = directBackend;
+
+ /**
* Subclasses should check this flag in case an abort message was sent
* and stop any internal iteration if false.
*/
@@ -454,12 +604,70 @@
this(contentHandler, prefix, nsURI);
this.schemaLocation = schemaLocation;
}
-
+
public void abort() {
running = false;
}
-
+
/**
+ * Set a mark() to which we can later "roll back" writes. After a call
+ * to mark(), the Translator stores pending write operations in memory
+ * until commit() is called. The pending writes can be discarded with
+ * the reset() method.
+ *
+ * Typically, one would use marks in conjunction with an exception handler:
+ *
+ * <pre>
+ * void encodeFoo(Foo f) {
+ * try {
+ * mark();
+ * element(foo.riskyMethod());
+ * element(foo.dangerousMethod());
+ * commit();
+ * } catch (BadThingHappened disaster) {
+ * mitigate(disaster);
+ * reset();
+ * }
+ * }
+ * </pre>
+ *
+ * @throws IllegalStateException if a mark is already set
+ */
+ protected void mark() {
+ if (backend == bufferedBackend) throw new IllegalStateException("Mark already set");
+ backend = bufferedBackend;
+ }
+
+ /**
+ * Discard pending write operations after a mark() has been set.
+ *
+ * This method is safe to call even if no mark is set - so it returns
+ * to a "known good" state as far as marks are concerned.
+ *
+ * @see #mark()
+ */
+ protected void reset() {
+ pending.clear();
+ backend = directBackend;
+ }
+
+ /**
+ * Commit pending write operations. After setting a mark, this method
+ * will commit the pending writes.
+ *
+ * @see #mark()
+ * @throws IllegalStateException if no mark is set
+ */
+ protected void commit() {
+ if (backend != bufferedBackend) throw new IllegalStateException("Can't commit without a mark");
+ for (Action a : pending) {
+ a.commit();
+ }
+ pending.clear();
+ backend = directBackend;
+ }
+
+ /**
* Utility method to copy namespace declarations from "sub" translators
* into this ns support...
*/
@@ -498,7 +706,7 @@
protected void element(String element, String content) {
element(element, content, NULL_ATTS);
}
-
+
/**
* Will only issue the provided element if content is non empty
* @param element
@@ -525,9 +733,12 @@
}
protected void start(String element, Attributes atts) {
+ backend.start(element, atts);
+ }
+
+ private void _start(String element, Attributes atts) {
try {
- String el = (prefix == null) ? element : (prefix + ":"
- + element);
+ String el = (prefix == null) ? element : (prefix + ":" + element);
contentHandler.startElement("", "", el, atts);
} catch (SAXException se) {
throw new RuntimeException(se);
@@ -535,6 +746,10 @@
}
protected void chars(String text) {
+ backend.chars(text);
+ }
+
+ private void _chars(String text) {
try {
char[] ch = text.toCharArray();
contentHandler.characters(ch, 0, ch.length);
@@ -544,6 +759,10 @@
}
protected void end(String element) {
+ backend.end(element);
+ }
+
+ private void _end(String element) {
try {
String el = (prefix == null) ? element : (prefix + ":"
+ element);
@@ -553,13 +772,18 @@
}
}
- protected void cdata( String cdata ) {
- if ( contentHandler instanceof LexicalHandler ) {
+ protected void cdata(String cdata) {
+ backend.cdata(cdata);
+ }
+
+ private void _cdata(String cdata) {
+ if (contentHandler instanceof LexicalHandler) {
LexicalHandler lexicalHandler = (LexicalHandler) contentHandler;
try {
lexicalHandler.startCDATA();
- chars(cdata);
- lexicalHandler.endCDATA();
+ char[] carray = cdata.toCharArray();
+ contentHandler.characters(carray, 0, carray.length);
+ lexicalHandler.endCDATA();
}
catch( SAXException e ) {
throw new RuntimeException( e );
Added: branches/2.7.x/modules/library/main/src/test/java/org/geotools/xml/ExampleTransformer.java
===================================================================
--- branches/2.7.x/modules/library/main/src/test/java/org/geotools/xml/ExampleTransformer.java (rev 0)
+++ branches/2.7.x/modules/library/main/src/test/java/org/geotools/xml/ExampleTransformer.java 2012-05-12 13:28:17 UTC (rev 38715)
@@ -0,0 +1,67 @@
+/*
+ * 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.xml;
+
+import org.geotools.xml.transform.TransformerBase;
+import org.geotools.xml.transform.Translator;
+import org.xml.sax.ContentHandler;
+
+public class ExampleTransformer extends TransformerBase {
+ private final int bufferEveryNth;
+ private final int exceptionEveryNth;
+ private final boolean ignoreErrors;
+
+ public ExampleTransformer(int bufferEveryNth, int exceptionEveryNth, boolean ignoreErrors) {
+ this.bufferEveryNth = bufferEveryNth;
+ this.exceptionEveryNth = exceptionEveryNth;
+ this.ignoreErrors = ignoreErrors;
+ }
+
+ public Translator createTranslator(ContentHandler handler) {
+ return new ExampleTranslator(handler);
+ }
+
+ private class ExampleTranslator extends TranslatorSupport {
+ public ExampleTranslator(ContentHandler handler) {
+ super(handler, "test", "http://geotools.org/test");
+ }
+
+ public void encode(Object o) {
+ Integer i = (Integer)o;
+ start("integers");
+ for (int j = 1; j <= i; j++) {
+ boolean buffer =
+ ((bufferEveryNth != 0) && (j % bufferEveryNth == 0));
+ boolean exception =
+ ((exceptionEveryNth != 0) && (j % exceptionEveryNth == 0));
+
+ try {
+ if (buffer) mark();
+ element("integer", String.valueOf(j));
+ if (exception) throw new RuntimeException();
+ if (buffer) commit();
+ } catch (RuntimeException e) {
+ if (!ignoreErrors) throw e;
+ } finally {
+ reset();
+ }
+ }
+
+ end("integers");
+ }
+ }
+}
Added: branches/2.7.x/modules/library/main/src/test/java/org/geotools/xml/TransformerBaseTest.java
===================================================================
--- branches/2.7.x/modules/library/main/src/test/java/org/geotools/xml/TransformerBaseTest.java (rev 0)
+++ branches/2.7.x/modules/library/main/src/test/java/org/geotools/xml/TransformerBaseTest.java 2012-05-12 13:28:17 UTC (rev 38715)
@@ -0,0 +1,85 @@
+/*
+ * 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.xml;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import javax.xml.transform.TransformerException;
+
+import junit.framework.TestCase;
+
+public class TransformerBaseTest extends TestCase {
+
+ public void testUnbufferedUsageNoErrors() throws FileNotFoundException, TransformerException {
+ String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test:integers xmlns=\"http://geotools.org/test\" xmlns:test=\"http://geotools.org/test\"><test:integer>1</test:integer><test:integer>2</test:integer><test:integer>3</test:integer><test:integer>4</test:integer><test:integer>5</test:integer><test:integer>6</test:integer><test:integer>7</test:integer><test:integer>8</test:integer><test:integer>9</test:integer><test:integer>10</test:integer></test:integers>";
+ ExampleTransformer tx = new ExampleTransformer(0, 0, false);
+ String actual = tx.transform(10);
+ assertEquals(expected, actual);
+ }
+
+ public void testUnbufferedUsageOneError() throws FileNotFoundException, TransformerException {
+ StringWriter w = new StringWriter();
+ try {
+ ExampleTransformer tx = new ExampleTransformer(0, 10, false);
+ tx.transform(10, w);
+ fail("Should have thrown an exception before reaching this point");
+ } catch (TransformerException e) {
+ String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test:integers xmlns=\"http://geotools.org/test\" xmlns:test=\"http://geotools.org/test\"><test:integer>1</test:integer><test:integer>2</test:integer><test:integer>3</test:integer><test:integer>4</test:integer><test:integer>5</test:integer><test:integer>6</test:integer><test:integer>7</test:integer><test:integer>8</test:integer><test:integer>9</test:integer><test:integer>10</test:integer>";
+ String actual = w.toString();
+ assertEquals(expected, actual);
+ }
+ }
+
+ public void testBufferedUsageNoErrors() throws FileNotFoundException, TransformerException {
+ String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test:integers xmlns=\"http://geotools.org/test\" xmlns:test=\"http://geotools.org/test\"><test:integer>1</test:integer><test:integer>2</test:integer><test:integer>3</test:integer><test:integer>4</test:integer><test:integer>5</test:integer><test:integer>6</test:integer><test:integer>7</test:integer><test:integer>8</test:integer><test:integer>9</test:integer><test:integer>10</test:integer></test:integers>";
+ ExampleTransformer tx = new ExampleTransformer(1, 0, false);
+ String actual = tx.transform(10);
+ assertEquals(expected, actual);
+ }
+
+ public void testBufferedUsageOneError() throws FileNotFoundException, TransformerException {
+ StringWriter w = new StringWriter();
+ try {
+ ExampleTransformer tx = new ExampleTransformer(1, 10, false);
+ tx.transform(10, w);
+ fail("Should have thrown an exception before reaching this point!");
+ } catch (TransformerException e) {
+ String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test:integers xmlns=\"http://geotools.org/test\" xmlns:test=\"http://geotools.org/test\"><test:integer>1</test:integer><test:integer>2</test:integer><test:integer>3</test:integer><test:integer>4</test:integer><test:integer>5</test:integer><test:integer>6</test:integer><test:integer>7</test:integer><test:integer>8</test:integer><test:integer>9</test:integer>";
+ String actual = w.toString();
+ assertEquals(expected, actual);
+ }
+ }
+
+ public void testBufferedUsageIgnoringOneError() throws FileNotFoundException, TransformerException {
+ ExampleTransformer tx = new ExampleTransformer(1, 10, true);
+ String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test:integers xmlns=\"http://geotools.org/test\" xmlns:test=\"http://geotools.org/test\"><test:integer>1</test:integer><test:integer>2</test:integer><test:integer>3</test:integer><test:integer>4</test:integer><test:integer>5</test:integer><test:integer>6</test:integer><test:integer>7</test:integer><test:integer>8</test:integer><test:integer>9</test:integer></test:integers>";
+ String actual = tx.transform(10);
+ assertEquals(expected, actual);
+ }
+
+ public void testBufferedUsageIgnoringMultipleErrors() throws FileNotFoundException, TransformerException {
+ ExampleTransformer tx = new ExampleTransformer(1, 2, true);
+ String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test:integers xmlns=\"http://geotools.org/test\" xmlns:test=\"http://geotools.org/test\"><test:integer>1</test:integer><test:integer>3</test:integer><test:integer>5</test:integer><test:integer>7</test:integer><test:integer>9</test:integer></test:integers>";
+ String actual = tx.transform(10);
+ assertEquals(expected, actual);
+ }
+}
|
|
From: <svn...@os...> - 2012-05-11 23:03:32
|
Author: groldan
Date: 2012-05-11 16:03:22 -0700 (Fri, 11 May 2012)
New Revision: 38714
Modified:
trunk/modules/library/opengis/src/main/java/org/opengis/filter/identity/Version.java
trunk/modules/library/opengis/src/test/java/org/opengis/filter/identity/VersionTest.java
Log:
GEOT-4141: disallow creating an org.opengis.filter.identity.Version with a non positive index argument
Modified: trunk/modules/library/opengis/src/main/java/org/opengis/filter/identity/Version.java
===================================================================
--- trunk/modules/library/opengis/src/main/java/org/opengis/filter/identity/Version.java 2012-05-11 10:22:30 UTC (rev 38713)
+++ trunk/modules/library/opengis/src/main/java/org/opengis/filter/identity/Version.java 2012-05-11 23:03:22 UTC (rev 38714)
@@ -77,10 +77,18 @@
this.union = UNION_ACTION | action.ordinal();
}
+ /**
+ * @param index a positive integer > 0, representing the 1 based index of the requested feature
+ * in its version history.
+ */
public Version(final Integer index) {
if (index == null) {
throw new IllegalArgumentException("index can't be null");
}
+ if (0 >= index.intValue()) {
+ throw new IllegalArgumentException("Invalid version index: " + index
+ + ". Must be a positive integer > 0.");
+ }
this.union = UNION_INTEGER | (long) index;
}
Modified: trunk/modules/library/opengis/src/test/java/org/opengis/filter/identity/VersionTest.java
===================================================================
--- trunk/modules/library/opengis/src/test/java/org/opengis/filter/identity/VersionTest.java 2012-05-11 10:22:30 UTC (rev 38713)
+++ trunk/modules/library/opengis/src/test/java/org/opengis/filter/identity/VersionTest.java 2012-05-11 23:03:22 UTC (rev 38714)
@@ -5,6 +5,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.util.Date;
@@ -29,6 +30,19 @@
@Test
public void versionInteger() {
+ try {
+ new Version(-1);
+ fail("Expected IAE on negative version");
+ } catch (IllegalArgumentException e) {
+ assertTrue(true);
+ }
+ try {
+ new Version(0);
+ fail("Expected IAE");
+ } catch (IllegalArgumentException e) {
+ assertTrue(true);
+ }
+
Integer testInt = new Integer(1234567890);
Version version = new Version(testInt);
|
Author: aaime
Date: 2012-05-11 03:22:30 -0700 (Fri, 11 May 2012)
New Revision: 38713
Added:
trunk/modules/library/render/src/test/java/org/geotools/renderer/lite/MetaBufferEstimatorTest.java
trunk/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/externalGraphicNoSize.sld
trunk/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/lineThick.sld
trunk/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/polygon.sld
Modified:
trunk/modules/library/render/src/main/java/org/geotools/renderer/lite/MetaBufferEstimator.java
Log:
[GEOT-4139] MetaBufferEstimator won't evaluate graphics size if the size is a NilExpression
Modified: trunk/modules/library/render/src/main/java/org/geotools/renderer/lite/MetaBufferEstimator.java
===================================================================
--- trunk/modules/library/render/src/main/java/org/geotools/renderer/lite/MetaBufferEstimator.java 2012-05-11 10:18:53 UTC (rev 38712)
+++ trunk/modules/library/render/src/main/java/org/geotools/renderer/lite/MetaBufferEstimator.java 2012-05-11 10:22:30 UTC (rev 38713)
@@ -58,10 +58,12 @@
import org.geotools.styling.StyledLayerDescriptor;
import org.geotools.styling.Symbolizer;
import org.geotools.styling.TextSymbolizer;
+import org.geotools.styling.TextSymbolizer2;
import org.geotools.styling.UserLayer;
import org.opengis.filter.Filter;
import org.opengis.filter.expression.Expression;
import org.opengis.filter.expression.Literal;
+import org.opengis.filter.expression.NilExpression;
import org.opengis.style.GraphicalSymbol;
/**
@@ -163,15 +165,22 @@
public void visit(Stroke stroke) {
try {
Expression width = stroke.getWidth();
- if (width != null) {
+ if (!isNull(width)) {
evaluateWidth(width);
}
+ if(stroke.getGraphicStroke() != null) {
+ stroke.getGraphicStroke().accept(this);
+ }
} catch (ClassCastException e) {
estimateAccurate = false;
LOGGER.info("Could not parse stroke width, "
+ "it's a literal but not a Number...");
}
}
+
+ protected boolean isNull(Expression exp) {
+ return exp == null || exp instanceof NilExpression;
+ }
/**
* @see org.geotools.styling.StyleVisitor#visit(org.geotools.styling.Symbolizer)
@@ -249,7 +258,13 @@
* @see org.geotools.styling.StyleVisitor#visit(org.geotools.styling.TextSymbolizer)
*/
public void visit(TextSymbolizer text) {
- // nothing to do here
+ // take into account label shields if any
+ if(text instanceof TextSymbolizer2) {
+ Graphic graphic = ((TextSymbolizer2) text).getGraphic();
+ if(graphic != null) {
+ graphic.accept(this);
+ }
+ }
}
/**
@@ -258,7 +273,7 @@
public void visit(Graphic gr) {
try {
Expression grSize = gr.getSize();
- if (grSize != null) {
+ if (!isNull(grSize)) {
evaluateWidth(grSize);
} else {
for (GraphicalSymbol gs : gr.graphicalSymbols()) {
Added: trunk/modules/library/render/src/test/java/org/geotools/renderer/lite/MetaBufferEstimatorTest.java
===================================================================
--- trunk/modules/library/render/src/test/java/org/geotools/renderer/lite/MetaBufferEstimatorTest.java (rev 0)
+++ trunk/modules/library/render/src/test/java/org/geotools/renderer/lite/MetaBufferEstimatorTest.java 2012-05-11 10:22:30 UTC (rev 38713)
@@ -0,0 +1,82 @@
+package org.geotools.renderer.lite;
+
+import static org.junit.Assert.*;
+
+import org.geotools.styling.Style;
+import org.junit.Test;
+
+public class MetaBufferEstimatorTest {
+
+ @Test
+ public void testExternalGraphic() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "externalGraphic.sld");
+ MetaBufferEstimator estimator = new MetaBufferEstimator();
+ style.accept(estimator);
+ assertTrue(estimator.isEstimateAccurate());
+ assertEquals(48, estimator.getBuffer());
+ }
+
+ @Test
+ public void testExternalGraphicNoSize() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "externalGraphicNoSize.sld");
+ MetaBufferEstimator estimator = new MetaBufferEstimator();
+ style.accept(estimator);
+ assertTrue(estimator.isEstimateAccurate());
+ assertEquals(64, estimator.getBuffer());
+ }
+
+ @Test
+ public void testMark() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "markCircle.sld");
+ MetaBufferEstimator estimator = new MetaBufferEstimator();
+ style.accept(estimator);
+ assertTrue(estimator.isEstimateAccurate());
+ assertEquals(32, estimator.getBuffer());
+ }
+
+ @Test
+ public void testThinLine() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "lineGray.sld");
+ MetaBufferEstimator estimator = new MetaBufferEstimator();
+ style.accept(estimator);
+ assertTrue(estimator.isEstimateAccurate());
+ assertEquals(1, estimator.getBuffer());
+ }
+
+ @Test
+ public void testThickLine() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "lineThick.sld");
+ MetaBufferEstimator estimator = new MetaBufferEstimator();
+ style.accept(estimator);
+ assertTrue(estimator.isEstimateAccurate());
+ assertEquals(4, estimator.getBuffer());
+ }
+
+ @Test
+ public void testGraphicStroke() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "lineRailway.sld");
+ MetaBufferEstimator estimator = new MetaBufferEstimator();
+ style.accept(estimator);
+ assertTrue(estimator.isEstimateAccurate());
+ assertEquals(8, estimator.getBuffer());
+ }
+
+ @Test
+ public void testPolygon() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "polygon.sld");
+ MetaBufferEstimator estimator = new MetaBufferEstimator();
+ style.accept(estimator);
+ assertTrue(estimator.isEstimateAccurate());
+ assertEquals(1, estimator.getBuffer());
+ }
+
+ @Test
+ public void testLabelShields() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "textLabelShield.sld");
+ MetaBufferEstimator estimator = new MetaBufferEstimator();
+ style.accept(estimator);
+ assertTrue(estimator.isEstimateAccurate());
+ assertEquals(32, estimator.getBuffer());
+ }
+
+}
Added: trunk/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/externalGraphicNoSize.sld
===================================================================
--- trunk/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/externalGraphicNoSize.sld (rev 0)
+++ trunk/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/externalGraphicNoSize.sld 2012-05-11 10:22:30 UTC (rev 38713)
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<StyledLayerDescriptor version="1.0.0" xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd">
+ <NamedLayer>
+
+ <Name>Icon</Name>
+ <UserStyle>
+ <FeatureTypeStyle>
+ <Rule>
+ <PointSymbolizer>
+ <Graphic>
+ <ExternalGraphic>
+ <OnlineResource xlink:type="simple" xlink:href="icon64.png" />
+ <Format>image/png</Format>
+ </ExternalGraphic>
+ </Graphic>
+ </PointSymbolizer>
+
+ </Rule>
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
\ No newline at end of file
Added: trunk/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/lineThick.sld
===================================================================
--- trunk/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/lineThick.sld (rev 0)
+++ trunk/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/lineThick.sld 2012-05-11 10:22:30 UTC (rev 38713)
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<StyledLayerDescriptor version="1.0.0" xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd">
+ <NamedLayer>
+
+ <Name>GrayLines</Name>
+ <UserStyle>
+ <FeatureTypeStyle>
+ <Rule>
+ <LineSymbolizer>
+ <Stroke>
+ <CssParameter name="stroke">0x440000</CssParameter>
+ <CssParameter name="stroke-width">4</CssParameter>
+ </Stroke>
+ </LineSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
\ No newline at end of file
Added: trunk/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/polygon.sld
===================================================================
--- trunk/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/polygon.sld (rev 0)
+++ trunk/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/polygon.sld 2012-05-11 10:22:30 UTC (rev 38713)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<StyledLayerDescriptor version="1.0.0"
+ xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"
+ xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <!-- a named layer is the basic building block of an sld document -->
+
+ <NamedLayer>
+ <UserStyle>
+ <FeatureTypeStyle>
+ <Rule>
+ <PolygonSymbolizer>
+ <Fill>
+ <CssParameter name="fill">#AAAAAA</CssParameter>
+ </Fill>
+ <Stroke/>
+ </PolygonSymbolizer>
+ </Rule>
+
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
+
|
Author: aaime
Date: 2012-05-11 03:18:53 -0700 (Fri, 11 May 2012)
New Revision: 38712
Added:
branches/2.7.x/modules/library/render/src/test/java/org/geotools/renderer/lite/MetaBufferEstimatorTest.java
branches/2.7.x/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/externalGraphicNoSize.sld
branches/2.7.x/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/lineThick.sld
branches/2.7.x/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/polygon.sld
Modified:
branches/2.7.x/modules/library/render/src/main/java/org/geotools/renderer/lite/MetaBufferEstimator.java
Log:
[GEOT-4139] MetaBufferEstimator won't evaluate graphics size if the size is a NilExpression
Modified: branches/2.7.x/modules/library/render/src/main/java/org/geotools/renderer/lite/MetaBufferEstimator.java
===================================================================
--- branches/2.7.x/modules/library/render/src/main/java/org/geotools/renderer/lite/MetaBufferEstimator.java 2012-05-11 09:05:43 UTC (rev 38711)
+++ branches/2.7.x/modules/library/render/src/main/java/org/geotools/renderer/lite/MetaBufferEstimator.java 2012-05-11 10:18:53 UTC (rev 38712)
@@ -58,10 +58,12 @@
import org.geotools.styling.StyledLayerDescriptor;
import org.geotools.styling.Symbolizer;
import org.geotools.styling.TextSymbolizer;
+import org.geotools.styling.TextSymbolizer2;
import org.geotools.styling.UserLayer;
import org.opengis.filter.Filter;
import org.opengis.filter.expression.Expression;
import org.opengis.filter.expression.Literal;
+import org.opengis.filter.expression.NilExpression;
import org.opengis.style.GraphicalSymbol;
/**
@@ -162,15 +164,22 @@
public void visit(Stroke stroke) {
try {
Expression width = stroke.getWidth();
- if (width != null) {
+ if (!isNull(width)) {
evaluateWidth(width);
}
+ if(stroke.getGraphicStroke() != null) {
+ stroke.getGraphicStroke().accept(this);
+ }
} catch (ClassCastException e) {
estimateAccurate = false;
LOGGER.info("Could not parse stroke width, "
+ "it's a literal but not a Number...");
}
}
+
+ protected boolean isNull(Expression exp) {
+ return exp == null || exp instanceof NilExpression;
+ }
/**
* @see org.geotools.styling.StyleVisitor#visit(org.geotools.styling.Symbolizer)
@@ -248,7 +257,13 @@
* @see org.geotools.styling.StyleVisitor#visit(org.geotools.styling.TextSymbolizer)
*/
public void visit(TextSymbolizer text) {
- // nothing to do here
+ // take into account label shields if any
+ if(text instanceof TextSymbolizer2) {
+ Graphic graphic = ((TextSymbolizer2) text).getGraphic();
+ if(graphic != null) {
+ graphic.accept(this);
+ }
+ }
}
/**
@@ -257,7 +272,7 @@
public void visit(Graphic gr) {
try {
Expression grSize = gr.getSize();
- if (grSize != null) {
+ if (!isNull(grSize)) {
evaluateWidth(grSize);
} else {
for (GraphicalSymbol gs : gr.graphicalSymbols()) {
Added: branches/2.7.x/modules/library/render/src/test/java/org/geotools/renderer/lite/MetaBufferEstimatorTest.java
===================================================================
--- branches/2.7.x/modules/library/render/src/test/java/org/geotools/renderer/lite/MetaBufferEstimatorTest.java (rev 0)
+++ branches/2.7.x/modules/library/render/src/test/java/org/geotools/renderer/lite/MetaBufferEstimatorTest.java 2012-05-11 10:18:53 UTC (rev 38712)
@@ -0,0 +1,82 @@
+package org.geotools.renderer.lite;
+
+import static org.junit.Assert.*;
+
+import org.geotools.styling.Style;
+import org.junit.Test;
+
+public class MetaBufferEstimatorTest {
+
+ @Test
+ public void testExternalGraphic() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "externalGraphic.sld");
+ MetaBufferEstimator estimator = new MetaBufferEstimator();
+ style.accept(estimator);
+ assertTrue(estimator.isEstimateAccurate());
+ assertEquals(48, estimator.getBuffer());
+ }
+
+ @Test
+ public void testExternalGraphicNoSize() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "externalGraphicNoSize.sld");
+ MetaBufferEstimator estimator = new MetaBufferEstimator();
+ style.accept(estimator);
+ assertTrue(estimator.isEstimateAccurate());
+ assertEquals(64, estimator.getBuffer());
+ }
+
+ @Test
+ public void testMark() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "markCircle.sld");
+ MetaBufferEstimator estimator = new MetaBufferEstimator();
+ style.accept(estimator);
+ assertTrue(estimator.isEstimateAccurate());
+ assertEquals(32, estimator.getBuffer());
+ }
+
+ @Test
+ public void testThinLine() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "lineGray.sld");
+ MetaBufferEstimator estimator = new MetaBufferEstimator();
+ style.accept(estimator);
+ assertTrue(estimator.isEstimateAccurate());
+ assertEquals(1, estimator.getBuffer());
+ }
+
+ @Test
+ public void testThickLine() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "lineThick.sld");
+ MetaBufferEstimator estimator = new MetaBufferEstimator();
+ style.accept(estimator);
+ assertTrue(estimator.isEstimateAccurate());
+ assertEquals(4, estimator.getBuffer());
+ }
+
+ @Test
+ public void testGraphicStroke() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "lineRailway.sld");
+ MetaBufferEstimator estimator = new MetaBufferEstimator();
+ style.accept(estimator);
+ assertTrue(estimator.isEstimateAccurate());
+ assertEquals(8, estimator.getBuffer());
+ }
+
+ @Test
+ public void testPolygon() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "polygon.sld");
+ MetaBufferEstimator estimator = new MetaBufferEstimator();
+ style.accept(estimator);
+ assertTrue(estimator.isEstimateAccurate());
+ assertEquals(1, estimator.getBuffer());
+ }
+
+ @Test
+ public void testLabelShields() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "textLabelShield.sld");
+ MetaBufferEstimator estimator = new MetaBufferEstimator();
+ style.accept(estimator);
+ assertTrue(estimator.isEstimateAccurate());
+ assertEquals(32, estimator.getBuffer());
+ }
+
+}
Added: branches/2.7.x/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/externalGraphicNoSize.sld
===================================================================
--- branches/2.7.x/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/externalGraphicNoSize.sld (rev 0)
+++ branches/2.7.x/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/externalGraphicNoSize.sld 2012-05-11 10:18:53 UTC (rev 38712)
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<StyledLayerDescriptor version="1.0.0" xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd">
+ <NamedLayer>
+
+ <Name>Icon</Name>
+ <UserStyle>
+ <FeatureTypeStyle>
+ <Rule>
+ <PointSymbolizer>
+ <Graphic>
+ <ExternalGraphic>
+ <OnlineResource xlink:type="simple" xlink:href="icon64.png" />
+ <Format>image/png</Format>
+ </ExternalGraphic>
+ </Graphic>
+ </PointSymbolizer>
+
+ </Rule>
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
\ No newline at end of file
Added: branches/2.7.x/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/lineThick.sld
===================================================================
--- branches/2.7.x/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/lineThick.sld (rev 0)
+++ branches/2.7.x/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/lineThick.sld 2012-05-11 10:18:53 UTC (rev 38712)
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<StyledLayerDescriptor version="1.0.0" xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd">
+ <NamedLayer>
+
+ <Name>GrayLines</Name>
+ <UserStyle>
+ <FeatureTypeStyle>
+ <Rule>
+ <LineSymbolizer>
+ <Stroke>
+ <CssParameter name="stroke">0x440000</CssParameter>
+ <CssParameter name="stroke-width">4</CssParameter>
+ </Stroke>
+ </LineSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
\ No newline at end of file
Added: branches/2.7.x/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/polygon.sld
===================================================================
--- branches/2.7.x/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/polygon.sld (rev 0)
+++ branches/2.7.x/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/polygon.sld 2012-05-11 10:18:53 UTC (rev 38712)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<StyledLayerDescriptor version="1.0.0"
+ xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"
+ xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <!-- a named layer is the basic building block of an sld document -->
+
+ <NamedLayer>
+ <UserStyle>
+ <FeatureTypeStyle>
+ <Rule>
+ <PolygonSymbolizer>
+ <Fill>
+ <CssParameter name="fill">#AAAAAA</CssParameter>
+ </Fill>
+ <Stroke/>
+ </PolygonSymbolizer>
+ </Rule>
+
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
+
|
Author: jive
Date: 2012-05-11 02:05:43 -0700 (Fri, 11 May 2012)
New Revision: 38711
Modified:
trunk/modules/library/main/src/main/java/org/geotools/feature/visitor/StandardDeviationVisitor.java
trunk/modules/library/main/src/main/java/org/geotools/filter/function/RangedClassifier.java
trunk/modules/library/main/src/main/java/org/geotools/filter/function/StandardDeviationFunction.java
trunk/modules/library/main/src/test/java/org/geotools/filter/function/StandardDeviationFunctionTest.java
Log:
Restore StandardDeviationFunctionTest and improve RangedClassifier null safety, GEOT-4138
Modified: trunk/modules/library/main/src/main/java/org/geotools/feature/visitor/StandardDeviationVisitor.java
===================================================================
--- trunk/modules/library/main/src/main/java/org/geotools/feature/visitor/StandardDeviationVisitor.java 2012-05-11 07:58:42 UTC (rev 38710)
+++ trunk/modules/library/main/src/main/java/org/geotools/feature/visitor/StandardDeviationVisitor.java 2012-05-11 09:05:43 UTC (rev 38711)
@@ -124,6 +124,10 @@
this.mean = 0;
}
+ /** mean value generated when calcualting standard deviation */
+ public double getMean() {
+ return mean;
+ }
/**
* @return the number of features which returned a NaN
*/
Modified: trunk/modules/library/main/src/main/java/org/geotools/filter/function/RangedClassifier.java
===================================================================
--- trunk/modules/library/main/src/main/java/org/geotools/filter/function/RangedClassifier.java 2012-05-11 07:58:42 UTC (rev 38710)
+++ trunk/modules/library/main/src/main/java/org/geotools/filter/function/RangedClassifier.java 2012-05-11 09:05:43 UTC (rev 38711)
@@ -43,8 +43,8 @@
*/
public final class RangedClassifier extends Classifier {
- Comparable min[];
- Comparable max[];
+ Comparable<?> min[];
+ Comparable<?> max[];
public RangedClassifier(Comparable min[], Comparable max[]) {
this.min = min;
@@ -52,10 +52,35 @@
//initialize titles
this.titles = new String[min.length];
for (int i = 0; i < titles.length; i++) {
- titles[i] = truncateZeros(min[i].toString()) + ".." + truncateZeros(max[i].toString());
+ titles[i] = generateTitle( min[i], max[i] );
}
}
-
+ /**
+ * Null safe title generation.
+ *
+ * @param min
+ * @param max
+ * @return generated title
+ */
+ private String generateTitle(Comparable<?> min, Comparable<?> max) {
+ if( min == null && max == null){
+ return "Other";
+ }
+ else if ( min == null ){
+ return "Below "+truncateZeros( String.valueOf( max ));
+ }
+ else if ( max == null ){
+ return "Above "+truncateZeros( String.valueOf( min ));
+ }
+ else {
+ return truncateZeros(String.valueOf(min)) + ".." + truncateZeros(String.valueOf(max));
+ }
+ }
+ /**
+ * Used to remove trailing zeros; preventing out put like 1.00000.
+ * @param str
+ * @return origional string with any trailing decimal places removed.
+ */
private String truncateZeros(String str) {
if (str.indexOf(".") > -1) {
while(str.endsWith("0")) {
@@ -84,25 +109,40 @@
return classify((Comparable) value);
}
- private int classify(Comparable val) {
- Comparable value = val;
+ @SuppressWarnings("rawtypes")
+ private int classify(Comparable<?> val) {
+ Comparable<?> value = val;
if (val instanceof Integer) { //convert to double as java is stupid
value = new Double(((Integer) val).intValue());
}
//check each slot and see if: min <= value < max
int last = min.length - 1;
for (int i = 0; i <= last; i++) {
- Comparable localMin = (Comparable) this.min[i];
- Comparable localMax = (Comparable) this.max[i];
+ Comparable localMin = this.min[i];
+ Comparable localMax = this.max[i];
- if (localMin.compareTo(value) < 1 && localMax.compareTo(value) > 0) {
+ if ((localMin == null || localMin.compareTo(value) < 1 ) &&
+ ( localMax == null || localMax.compareTo(value) > 0)) {
return i;
}
}
- if (max[last].compareTo(value) == 0) { //if value = max, put it in the last slot
+ if (compareTo(max[last],value) == 0) { //if value = max, put it in the last slot
return last;
}
- return -1;
+ return -1; // value does not fit into any of the provided categories
}
+
+ private int compareTo(Comparable compare, Comparable value) {
+ if( compare == null && value == null ){
+ return 0;
+ }
+ else if( compare == null ){
+ return -1;
+ }
+ else if( value == null ){
+ return +1;
+ }
+ return value.compareTo(compare);
+ }
}
Modified: trunk/modules/library/main/src/main/java/org/geotools/filter/function/StandardDeviationFunction.java
===================================================================
--- trunk/modules/library/main/src/main/java/org/geotools/filter/function/StandardDeviationFunction.java 2012-05-11 07:58:42 UTC (rev 38710)
+++ trunk/modules/library/main/src/main/java/org/geotools/filter/function/StandardDeviationFunction.java 2012-05-11 09:05:43 UTC (rev 38711)
@@ -47,27 +47,26 @@
private Object calculate(SimpleFeatureCollection featureCollection) {
try {
int classNum = getClasses();
- // find the average
- AverageVisitor averageVisit = new AverageVisitor(getExpression());
- if (progress == null) progress = new NullProgressListener();
- featureCollection.accepts(averageVisit, progress);
- if (progress.isCanceled()) return null;
- CalcResult calcResult = averageVisit.getResult();
- if (calcResult == null) return null;
- double average = calcResult.toDouble();
- // find the standard deviation
- StandardDeviationVisitor sdVisit = new StandardDeviationVisitor(getExpression(), average);
- featureCollection.accepts(sdVisit, progress);
- if (progress.isCanceled()) return null;
- calcResult = sdVisit.getResult();
- if (calcResult == null) return null;
- double standardDeviation = calcResult.toDouble();
+
+ // find the standard deviation
+ StandardDeviationVisitor sdVisit = new StandardDeviationVisitor(getExpression());
+
+ featureCollection.accepts(sdVisit, progress);
+ if (progress != null && progress.isCanceled()) {
+ return null;
+ }
+ CalcResult calcResult = sdVisit.getResult();
+ if (calcResult == null) {
+ return null;
+ }
+ double standardDeviation = calcResult.toDouble();
+
//figure out the min and max values
Double min[] = new Double[classNum];
Double max[] = new Double[classNum];
for (int i = 0; i < classNum; i++) {
- min[i] = getMin(i, classNum, average, standardDeviation);
- max[i] = getMax(i, classNum, average, standardDeviation);
+ min[i] = getMin(i, classNum, sdVisit.getMean(), standardDeviation);
+ max[i] = getMax(i, classNum, sdVisit.getMean(), standardDeviation);
}
return new RangedClassifier(min, max);
} catch (IOException e) {
Modified: trunk/modules/library/main/src/test/java/org/geotools/filter/function/StandardDeviationFunctionTest.java
===================================================================
--- trunk/modules/library/main/src/test/java/org/geotools/filter/function/StandardDeviationFunctionTest.java 2012-05-11 07:58:42 UTC (rev 38710)
+++ trunk/modules/library/main/src/test/java/org/geotools/filter/function/StandardDeviationFunctionTest.java 2012-05-11 09:05:43 UTC (rev 38711)
@@ -20,6 +20,8 @@
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.feature.FeatureCollections;
+import org.opengis.feature.Feature;
+import org.opengis.feature.FeatureVisitor;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.filter.expression.Function;
import org.opengis.filter.expression.Literal;
@@ -72,46 +74,72 @@
assertEquals(12, func.getClasses());
}
- public void xTestGetValue() throws Exception{
+ public void testGetValue() throws Exception{
//doesn't work yet?
Literal classes = ff.literal(5);
PropertyName exp = ff.property("foo");
- Function func = ff.function("StandardDeviation", exp, classes);
+ Function standardDeviation = ff.function("StandardDeviation", exp, classes);
+ assertNotNull( "step 1 - standard deviation function", standardDeviation );
+ final Classifier classifer = standardDeviation.evaluate( featureCollection, Classifier.class );
+ featureCollection.accepts( new FeatureVisitor() {
+ @Override
+ public void visit(Feature f) {
+ SimpleFeature feature = (SimpleFeature) f;
+ Object value = feature.getAttribute("foo");
+ assertNotNull( feature.getID()+" foo", value );
+
+ int slot = classifer.classify( value );
+ assertNotNull( "Slot "+slot, classifer.getTitle( slot ) );
+ }
+ }, null );
+
+ Function classify = ff.function("classify", exp, ff.literal(classifer));
+ assertNotNull( "step 2 - classify function", classify );
+
SimpleFeatureIterator list = featureCollection.features();
+
//feature 1
SimpleFeature f = list.next();
- int slot = ((Number)func.evaluate(f)).intValue();
- assertEquals(1, slot);
+ Integer slot = classify.evaluate(f,Integer.class);
+ assertEquals( "value "+f.getAttribute("foo"), 1, slot.intValue());
+
//feature 2
f = list.next();
- slot = ((Number)func.evaluate(f)).intValue();
- assertEquals(4, slot);
+ slot = classify.evaluate(f,Integer.class);
+ assertEquals( "value "+f.getAttribute("foo"),4, slot.intValue());
+
+
//feature 3
f = list.next();
- slot = ((Number)func.evaluate(f)).intValue();
- assertEquals(2, slot);
+ slot = classify.evaluate(f,Integer.class);
+ assertEquals( "value "+f.getAttribute("foo"),2, slot.intValue());
+
//feature 4
f = list.next();
- slot = ((Number)func.evaluate(f)).intValue();
- assertEquals(2, slot);
+ slot = classify.evaluate(f,Integer.class);
+ assertEquals( "value "+f.getAttribute("foo"),2, slot.intValue());
+
+
//feature 5
f = list.next();
- slot = ((Number)func.evaluate(f)).intValue();
- assertEquals(2, slot);
+ slot = classify.evaluate(f,Integer.class);
+ assertEquals( "value "+f.getAttribute("foo"),2, slot.intValue());
+
+
//feature 6
f = list.next();
- slot = ((Number)func.evaluate(f)).intValue();
- assertEquals(3, slot);
+ slot = classify.evaluate(f,Integer.class);
+ assertEquals( "value "+f.getAttribute("foo"),3, slot.intValue());
+
//feature 7
f = list.next();
- slot = ((Number)func.evaluate(f)).intValue();
- assertEquals(1, slot);
+ slot = classify.evaluate(f,Integer.class);
+ assertEquals( "value "+f.getAttribute("foo"),1, slot.intValue());
+
//feature 8
f = list.next();
- slot = ((Number)func.evaluate(f)).intValue();
- assertEquals(1, slot);
+ slot = classify.evaluate(f,Integer.class);
+ assertEquals( "value "+f.getAttribute("foo"),1, slot.intValue());
}
-
-
}
|
|
From: <svn...@os...> - 2012-05-11 07:58:53
|
Author: jive
Date: 2012-05-11 00:58:42 -0700 (Fri, 11 May 2012)
New Revision: 38710
Modified:
trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/AuthorityBackedFactory.java
Log:
Reduce AuthorityBackedFactory reporting down to finer to hide an expected message from NADCONTransform when it is not supplied with the support files required for some transforms, see GEOT-4124
Modified: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/AuthorityBackedFactory.java
===================================================================
--- trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/AuthorityBackedFactory.java 2012-05-10 09:56:21 UTC (rev 38709)
+++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/AuthorityBackedFactory.java 2012-05-11 07:58:42 UTC (rev 38710)
@@ -262,7 +262,7 @@
* Other kind of error. It may be more serious, but the super-class is capable
* to provides a raisonable default behavior. Log as a warning and lets continue.
*/
- log(exception, authorityFactory);
+ log(exception, authorityFactory,Level.FINER);
return null;
}
if (operations != null) {
@@ -433,7 +433,13 @@
* Logs a warning when an object can't be created from the specified factory.
*/
private static void log(final Exception exception, final AuthorityFactory factory) {
- final LogRecord record = Loggings.format(Level.WARNING,
+ log( exception, factory, Level.WARNING);
+ }
+ /**
+ * Logs a warning when an object can't be created from the specified factory.
+ */
+ private static void log(final Exception exception, final AuthorityFactory factory, Level level) {
+ final LogRecord record = Loggings.format( level,
LoggingKeys.CANT_CREATE_COORDINATE_OPERATION_$1,
factory.getAuthority().getTitle());
record.setSourceClassName(AuthorityBackedFactory.class.getName());
|
Author: jive
Date: 2012-05-10 02:56:21 -0700 (Thu, 10 May 2012)
New Revision: 38709
Modified:
trunk/modules/library/referencing/src/test/java/org/geotools/referencing/factory/epsg/FallbackAuthorityFactoryTest.java
trunk/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/factory/URN_EPSG_Test.java
Log:
Use CRS reset to clear the slate during testing of anything with the fallback factory, see GEOT-4134
Modified: trunk/modules/library/referencing/src/test/java/org/geotools/referencing/factory/epsg/FallbackAuthorityFactoryTest.java
===================================================================
--- trunk/modules/library/referencing/src/test/java/org/geotools/referencing/factory/epsg/FallbackAuthorityFactoryTest.java 2012-05-10 09:16:34 UTC (rev 38708)
+++ trunk/modules/library/referencing/src/test/java/org/geotools/referencing/factory/epsg/FallbackAuthorityFactoryTest.java 2012-05-10 09:56:21 UTC (rev 38709)
@@ -60,6 +60,8 @@
@Before
public void setUp() {
assertNull(extra);
+
+ CRS.reset("all");
extra = new FactoryEPSGExtra();
ReferencingFactoryFinder.addAuthorityFactory(extra);
ReferencingFactoryFinder.scanForPlugins();
@@ -81,12 +83,15 @@
*/
@Test
public void testFactoryOrdering() {
- Set factories = ReferencingFactoryFinder.getCRSAuthorityFactories(null);
+ Set<CRSAuthorityFactory> factories = ReferencingFactoryFinder.getCRSAuthorityFactories(null);
+ for( CRSAuthorityFactory factory : factories ){
+ System.out.println("--> "+factory.getClass().getSimpleName() );
+ }
boolean foundWkt = false;
boolean foundExtra = false;
- for (Iterator it = factories.iterator(); it.hasNext();) {
+ for (Iterator<CRSAuthorityFactory> it = factories.iterator(); it.hasNext();) {
CRSAuthorityFactory factory = (CRSAuthorityFactory) it.next();
- Class type = factory.getClass();
+ Class<?> type = factory.getClass();
if (VERBOSE) {
System.out.println(type);
}
Modified: trunk/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/factory/URN_EPSG_Test.java
===================================================================
--- trunk/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/factory/URN_EPSG_Test.java 2012-05-10 09:16:34 UTC (rev 38708)
+++ trunk/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/factory/URN_EPSG_Test.java 2012-05-10 09:56:21 UTC (rev 38709)
@@ -88,6 +88,8 @@
* Tests versioning.
*/
public void testVersion() throws FactoryException {
+ CRS.reset("all");
+
CoordinateReferenceSystem expected = CRS.decode("EPSG:4326");
final String version = String.valueOf(CRS.getVersion("EPSG"));
final String urn = "urn:ogc:def:crs:EPSG:" + version + ":4326";
|
Author: ang05a
Date: 2012-05-10 02:16:34 -0700 (Thu, 10 May 2012)
New Revision: 38708
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/filter/XPath.java
trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/ComplexTestData.java
trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/filter/UnmappingFilterVisitorTest.java
trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/filter/XPathTest.java
Log:
Brett Walker's patch for GEOT-4117: Select XML attributes on the root element
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-05-09 10:37:32 UTC (rev 38707)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/FeatureTypeMapping.java 2012-05-10 09:16:34 UTC (rev 38708)
@@ -269,19 +269,24 @@
}
List expressions = getExpressions(candidates);
- // does the last step refer to a client property of the parent step?
+ // Does the last step refer to a client property of the parent step?
+ // The parent step could be the root element which may not be on the path.
// i.e. a client property maps to an xml attribute, and the step list
// could have been generated from an xpath of the form
- // propA/propB@attName
- if (candidates.size() == 0 && propertyName.size() > 1) {
+ // @attName or propA/propB@attName
+ if (candidates.size() == 0 && propertyName.size() > 0) {
XPath.Step clientPropertyStep = (Step) propertyName.get(propertyName.size() - 1);
Name clientPropertyName = Types.toTypeName(clientPropertyStep.getName());
+ XPath.StepList parentPath;
- XPath.StepList parentPath = new XPath.StepList(propertyName);
- parentPath.remove(parentPath.size() - 1);
+ if (propertyName.size() == 1) {
+ parentPath = XPath.rootElementSteps(this.target, this.namespaces);
+ } else {
+ parentPath = new XPath.StepList(propertyName);
+ parentPath.remove(parentPath.size() - 1);
+ }
candidates = getAttributeMappingsIgnoreIndex(parentPath);
-
expressions = getClientPropertyExpressions(candidates, clientPropertyName, parentPath);
if (expressions.isEmpty()) {
// this might be a wrapper mapping for another complex mapping
Modified: 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/complex/filter/XPath.java 2012-05-09 10:37:32 UTC (rev 38707)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/filter/XPath.java 2012-05-10 09:16:34 UTC (rev 38708)
@@ -480,6 +480,29 @@
}
/**
+ * Returns the list of steps in an x-path expression that represents the root element.
+ *
+ * @param root
+ * non null descriptor of the root attribute, generally the Feature descriptor.
+ * @param namespaces
+ * namespace support for generating qnames from namespaces.
+ * @return A list of unique of steps in an xpath expression.
+ * @throws IllegalArgumentException
+ * if <code>root</code> is undefined.
+ */
+ public static StepList rootElementSteps(final AttributeDescriptor rootElement,
+ final NamespaceSupport namespaces) throws IllegalArgumentException {
+
+ if (rootElement == null) {
+ throw new NullPointerException("root");
+ }
+ StepList steps = new StepList();
+ QName qName = Types.toQName(rootElement.getName(), namespaces);
+ steps.add(new Step(qName, 1, false, false));
+ return steps;
+ }
+
+ /**
* Returns the list of stepts in <code>xpathExpression</code> by cleaning it up removing
* unnecessary elements.
* <p>
Modified: trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/ComplexTestData.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/ComplexTestData.java 2012-05-09 10:37:32 UTC (rev 38707)
+++ trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/ComplexTestData.java 2012-05-10 09:16:34 UTC (rev 38708)
@@ -424,4 +424,56 @@
assertEquals(superType, type.getSuper());
}
+ /**
+ * Similar to the feature type return by {@link createExample01MultiValuedComplexProperty}
+ * except that there is no namespace uri specified.
+ *
+ * @param typeFactory
+ * @return FeatureType
+ */
+ public static FeatureType createExample05NoNamespaceURI(FeatureTypeFactory typeFactory) {
+ FeatureType wqPlusType;
+
+ TypeBuilder builder = new TypeBuilder(typeFactory);
+
+ builder.setName("sitename");
+ builder.setBinding(String.class);
+ AttributeType SITENAME = builder.attribute();
+
+ builder.setName("anzlic_noType");
+ builder.setBinding(String.class);
+ AttributeType ANZLIC_NO = builder.attribute();
+
+ builder.setName("locationType");
+ builder.setBinding(Point.class);
+ GeometryType LOCATION = builder.geometry();
+
+ // build complex attribute
+ AttributeType MEASUREMENT = createMeasurementType(typeFactory);
+
+ builder.setName("project_noType");
+ builder.setBinding(String.class);
+ AttributeType PROJECT_NO = builder.attribute();
+
+ builder.setName("wq_plus");
+
+ builder.cardinality(1, 1);
+ builder.addAttribute("sitename", SITENAME);
+
+ builder.cardinality(0, 1);
+ builder.addAttribute("anzlic_no", ANZLIC_NO);
+
+ builder.cardinality(0, 1);
+ builder.addAttribute("location", LOCATION);
+
+ builder.cardinality(0, Integer.MAX_VALUE);
+ builder.addAttribute("measurement", MEASUREMENT);
+
+ builder.cardinality(0, 1);
+ builder.addAttribute("project_no", PROJECT_NO);
+
+ wqPlusType = builder.feature();
+
+ return wqPlusType;
+ }
}
Modified: trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/filter/UnmappingFilterVisitorTest.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/filter/UnmappingFilterVisitorTest.java 2012-05-09 10:37:32 UTC (rev 38707)
+++ trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/filter/UnmappingFilterVisitorTest.java 2012-05-10 09:16:34 UTC (rev 38708)
@@ -41,7 +41,6 @@
import org.geotools.data.FeatureSource;
import org.geotools.data.complex.AppSchemaDataAccess;
import org.geotools.data.complex.AttributeMapping;
-import org.geotools.data.complex.DataAccessRegistry;
import org.geotools.data.complex.FeatureTypeMapping;
import org.geotools.data.complex.TestData;
import org.geotools.data.complex.filter.XPath.Step;
@@ -53,14 +52,12 @@
import org.geotools.feature.TypeBuilder;
import org.geotools.feature.Types;
import org.geotools.feature.type.UniqueNameFeatureTypeFactoryImpl;
-import org.geotools.filter.FidFilterImpl;
import org.geotools.filter.FilterFactoryImplNamespaceAware;
import org.geotools.filter.IsEqualsToImpl;
import org.geotools.filter.OrImpl;
import org.geotools.gml3.GML;
import org.geotools.test.AppSchemaTestSupport;
import org.geotools.xlink.XLINK;
-import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -399,7 +396,58 @@
assertTrue(unrolled.get(0) instanceof Expression);
}
+ /**
+ * An x-path expression may target a "client property" mapping (in xml land, an xml attribute
+ * rather than a xml element).
+ *
+ * @throws Exception
+ */
@Test
+ public void testPropertyNameWithGmlIdAttribute() throws Exception {
+ final String XMMLNS = "http://www.opengis.net/xmml";
+ final Name typeName = new NameImpl(XMMLNS, "Borehole");
+
+ AppSchemaDataAccess complexDs = (AppSchemaDataAccess) mappingDataStore;
+
+ mapping = complexDs.getMappingByElement(typeName);
+
+ NamespaceSupport namespaces = new NamespaceSupport();
+ namespaces.declarePrefix("gml", GML.NAMESPACE);
+ namespaces.declarePrefix("xmml", XMMLNS);
+ namespaces.declarePrefix("xlink", XLINK.NAMESPACE);
+
+ visitor = new UnmappingFilterVisitor(mapping);
+ FilterFactory2 ff = new FilterFactoryImplNamespaceAware(namespaces);
+
+ String xpathExpression = "@gml:id";
+ PropertyName propNameExpression = ff.property(xpathExpression);
+
+ List /* <Expression> */unrolled = (List) propNameExpression.accept(visitor, null);
+ assertNotNull(unrolled);
+ assertEquals(1, unrolled.size());
+ assertTrue(unrolled.get(0) instanceof Expression);
+ assertEquals(((Expression) unrolled.get(0)).toString(), "strConcat([bh.], [BGS_ID])");
+
+ xpathExpression = "/@gml:id";
+ propNameExpression = ff.property(xpathExpression);
+
+ unrolled = (List) propNameExpression.accept(visitor, null);
+ assertNotNull(unrolled);
+ assertEquals(1, unrolled.size());
+ assertTrue(unrolled.get(0) instanceof Expression);
+ assertEquals(((Expression) unrolled.get(0)).toString(), "strConcat([bh.], [BGS_ID])");
+
+ xpathExpression = "xmml:Borehole/@gml:id";
+ propNameExpression = ff.property(xpathExpression);
+
+ unrolled = (List) propNameExpression.accept(visitor, null);
+ assertNotNull(unrolled);
+ assertEquals(1, unrolled.size());
+ assertTrue(unrolled.get(0) instanceof Expression);
+ assertEquals(((Expression) unrolled.get(0)).toString(), "strConcat([bh.], [BGS_ID])");
+ }
+
+ @Test
public void testBetweenFilter() throws Exception {
PropertyIsBetween bf = ff.between(ff.property("measurement/result"), ff.literal(1), ff
.literal(2), MatchAction.ALL);
Modified: trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/filter/XPathTest.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/filter/XPathTest.java 2012-05-09 10:37:32 UTC (rev 38707)
+++ trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/filter/XPathTest.java 2012-05-10 09:16:34 UTC (rev 38708)
@@ -172,4 +172,54 @@
assertFalse(Types.isSimpleContentType(GMLSchema.ABSTRACTFEATURECOLLECTIONTYPE_TYPE));
}
+ /**
+ * Test that the {@link StepList} for the root element is properly formed.
+ */
+ @Test
+ public void testRootElementSteps() {
+ NamespaceSupport namespaces = new NamespaceSupport();
+
+ try {
+ XPath.rootElementSteps(null, namespaces);
+ fail("passed null");
+ } catch (NullPointerException e) {
+ }
+
+ FeatureType complexType = ComplexTestData
+ .createExample05NoNamespaceURI(new UniqueNameFeatureTypeFactoryImpl());
+ Name name = complexType.getName();
+ AttributeDescriptor descriptor = new AttributeDescriptorImpl(complexType, name, 0,
+ Integer.MAX_VALUE, true, null);
+
+ try {
+ XPath.rootElementSteps(descriptor, namespaces);
+ } catch (NullPointerException e) {
+ fail("failed null");
+ }
+
+ assertEquals(1, XPath.rootElementSteps(descriptor, namespaces).size());
+ XPath.Step step = XPath.rootElementSteps(descriptor, namespaces).get(0);
+ QName rootQName = new QName(name.getNamespaceURI(), name.getLocalPart(), "");
+ assertEquals(rootQName, step.getName());
+
+ complexType = ComplexTestData
+ .createExample01MultiValuedComplexProperty(new UniqueNameFeatureTypeFactoryImpl());
+ name = complexType.getName();
+ descriptor = new AttributeDescriptorImpl(complexType, name, 0, Integer.MAX_VALUE, true,
+ null);
+
+ String prefix = "wq";
+ namespaces.declarePrefix(prefix, name.getNamespaceURI());
+
+ try {
+ XPath.rootElementSteps(descriptor, namespaces);
+ } catch (NullPointerException e) {
+ fail("failed null");
+ }
+
+ assertEquals(1, XPath.rootElementSteps(descriptor, namespaces).size());
+ step = XPath.rootElementSteps(descriptor, namespaces).get(0);
+ rootQName = new QName(name.getNamespaceURI(), name.getLocalPart(), prefix);
+ assertEquals(rootQName, step.getName());
+ }
}
|
|
From: <svn...@os...> - 2012-05-09 10:37:43
|
Author: danieleromagnoli Date: 2012-05-09 03:37:32 -0700 (Wed, 09 May 2012) New Revision: 38707 Modified: branches/2.7.x/modules/unsupported/matfile5/pom.xml Log: Removing old repository reference from unsupported matlab plugin Modified: branches/2.7.x/modules/unsupported/matfile5/pom.xml =================================================================== --- branches/2.7.x/modules/unsupported/matfile5/pom.xml 2012-05-09 10:36:38 UTC (rev 38706) +++ branches/2.7.x/modules/unsupported/matfile5/pom.xml 2012-05-09 10:37:32 UTC (rev 38707) @@ -29,6 +29,10 @@ <name>SAS Matlab grid coverage readers</name> <url>http://maven.geotools.fr/reports/modules/unsupported/sas/</url> + <properties> + <imageio.mat.version>1.1M012010</imageio.mat.version> + </properties> + <scm> <connection> scm:svn:http://svn.osgeo.org/geotools/trunk/modules/unsupported/matfile5 @@ -75,14 +79,6 @@ </developer> </developers> - <repositories> - <repository> - <id>geosolutions</id> - <name>GeoSolutions libraries repository</name> - <url>http://mvn.geo-solutions.it/</url> - </repository> - </repositories> - <!-- =========================================================== --> <!-- Dependency Management --> <!-- =========================================================== --> @@ -95,12 +91,12 @@ <dependency> <groupId>it.geosolutions.imageio-ext</groupId> <artifactId>imageio-ext-mat-sas</artifactId> - <version>1.1M012010</version> + <version>${imageio.mat.version}</version> </dependency> <dependency> <groupId>it.geosolutions.imageio-ext</groupId> <artifactId>imageio-ext-imagereadmt</artifactId> - <version>1.1M012010</version> + <version>${imageio.mat.version}</version> </dependency> <dependency> <groupId>org.geotools</groupId> |
|
From: <svn...@os...> - 2012-05-09 10:36:50
|
Author: danieleromagnoli Date: 2012-05-09 03:36:38 -0700 (Wed, 09 May 2012) New Revision: 38706 Modified: trunk/modules/unsupported/matfile5/pom.xml Log: Removing old repository reference from unsupported matlab plugin Modified: trunk/modules/unsupported/matfile5/pom.xml =================================================================== --- trunk/modules/unsupported/matfile5/pom.xml 2012-05-08 20:50:44 UTC (rev 38705) +++ trunk/modules/unsupported/matfile5/pom.xml 2012-05-09 10:36:38 UTC (rev 38706) @@ -29,6 +29,10 @@ <name>SAS Matlab grid coverage readers</name> <url>http://maven.geotools.fr/reports/modules/unsupported/sas/</url> + <properties> + <imageio.mat.version>1.1M012010</imageio.mat.version> + </properties> + <scm> <connection> scm:svn:http://svn.osgeo.org/geotools/trunk/modules/unsupported/matfile5 @@ -75,14 +79,6 @@ </developer> </developers> - <repositories> - <repository> - <id>geosolutions</id> - <name>GeoSolutions libraries repository</name> - <url>http://mvn.geo-solutions.it/</url> - </repository> - </repositories> - <!-- =========================================================== --> <!-- Dependency Management --> <!-- =========================================================== --> @@ -95,12 +91,12 @@ <dependency> <groupId>it.geosolutions.imageio-ext</groupId> <artifactId>imageio-ext-mat-sas</artifactId> - <version>1.1M012010</version> + <version>${imageio.mat.version}</version> </dependency> <dependency> <groupId>it.geosolutions.imageio-ext</groupId> <artifactId>imageio-ext-imagereadmt</artifactId> - <version>1.1M012010</version> + <version>${imageio.mat.version}</version> </dependency> <dependency> <groupId>org.geotools</groupId> |
|
From: <svn...@os...> - 2012-05-08 20:50:50
|
Author: nielscharlier
Date: 2012-05-08 13:50:44 -0700 (Tue, 08 May 2012)
New Revision: 38705
Modified:
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/NestedAttributeMapping.java
Log:
app-schema fix null filters bug
Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/NestedAttributeMapping.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/NestedAttributeMapping.java 2012-05-06 10:24:36 UTC (rev 38704)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/NestedAttributeMapping.java 2012-05-08 20:50:44 UTC (rev 38705)
@@ -45,6 +45,7 @@
import org.opengis.filter.identity.FeatureId;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.xml.sax.helpers.NamespaceSupport;
+import java.util.Collections;
/**
* This class represents AttributeMapping for attributes that are nested inside another complex
@@ -355,6 +356,10 @@
public List<Feature> getFeatures(Object source, Object foreignKeyValue, List<Object> idValues,
CoordinateReferenceSystem reprojection, Object feature, List<PropertyName> selectedProperties, boolean includeMandatory) throws IOException {
+ if (foreignKeyValue == null) {
+ return Collections.<Feature>emptyList();
+ }
+
if (isSameSource()) {
// if linkField is null, this method shouldn't be called because the mapping
// should use the same table, and handles it differently
|
|
From: <svn...@os...> - 2012-05-06 10:24:46
|
Author: aaime
Date: 2012-05-06 03:24:36 -0700 (Sun, 06 May 2012)
New Revision: 38704
Modified:
trunk/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostgisNGJNDIDataStoreFactory.java
Log:
Remove extra unexpected param which makes sense only for factories building their own connection pool
Modified: trunk/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostgisNGJNDIDataStoreFactory.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostgisNGJNDIDataStoreFactory.java 2012-05-06 10:24:21 UTC (rev 38703)
+++ trunk/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostgisNGJNDIDataStoreFactory.java 2012-05-06 10:24:36 UTC (rev 38704)
@@ -44,7 +44,6 @@
parameters.put(LOOSEBBOX.key, LOOSEBBOX);
parameters.put(ESTIMATED_EXTENTS.key, ESTIMATED_EXTENTS);
parameters.put(PREPARED_STATEMENTS.key, PREPARED_STATEMENTS);
- parameters.put(MAX_OPEN_PREPARED_STATEMENTS.key, MAX_OPEN_PREPARED_STATEMENTS);
parameters.put(ENCODE_FUNCTIONS.key, ENCODE_FUNCTIONS);
}
}
|
Author: aaime
Date: 2012-05-06 03:24:21 -0700 (Sun, 06 May 2012)
New Revision: 38703
Added:
trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/PropertyCoordinateOperationAuthorityFactory.java
trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/CoordinateOperationFactoryUsingWKT.java
trunk/modules/library/referencing/src/test/java/org/geotools/referencing/factory/epsg/CoordinateOperationFactoryUsingWKTTest.java
trunk/modules/library/referencing/src/test/resources/org/geotools/referencing/factory/epsg/epsg_operations.properties
trunk/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/factory/epsg/LongitudeFirstFactoryOverrideTest.java
trunk/modules/plugin/epsg-hsql/src/test/resources/org/geotools/referencing/factory/epsg/
trunk/modules/plugin/epsg-hsql/src/test/resources/org/geotools/referencing/factory/epsg/epsg.properties
trunk/modules/plugin/epsg-hsql/src/test/resources/org/geotools/referencing/factory/epsg/epsg_operations.properties
Modified:
trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/DeferredAuthorityFactory.java
trunk/modules/library/referencing/src/main/java/org/geotools/referencing/wkt/MathTransformParser.java
trunk/modules/library/referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.CoordinateOperationAuthorityFactory
trunk/modules/library/referencing/src/test/resources/org/geotools/referencing/factory/epsg/epsg.properties
trunk/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/factory/URN_EPSG_Test.java
Log:
[GEOT-4108] File based CoordinateOperation factory
Modified: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/DeferredAuthorityFactory.java
===================================================================
--- trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/DeferredAuthorityFactory.java 2012-05-04 15:22:05 UTC (rev 38702)
+++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/DeferredAuthorityFactory.java 2012-05-06 10:24:21 UTC (rev 38703)
@@ -126,7 +126,7 @@
* @throws FactoryException if the creation of backing store failed.
*/
@Override
- final AbstractAuthorityFactory getBackingStore() throws FactoryException {
+ protected final AbstractAuthorityFactory getBackingStore() throws FactoryException {
if (backingStore == null) {
synchronized (this) {
if(backingStore == null) {
Added: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/PropertyCoordinateOperationAuthorityFactory.java
===================================================================
--- trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/PropertyCoordinateOperationAuthorityFactory.java (rev 0)
+++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/PropertyCoordinateOperationAuthorityFactory.java 2012-05-06 10:24:21 UTC (rev 38703)
@@ -0,0 +1,342 @@
+/*
+ * GeoTools - The Open Source Java GIS Toolkit
+ * http://geotools.org
+ *
+ * (C) 2002-2012, 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.referencing.factory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.geotools.referencing.CRS;
+import org.geotools.referencing.operation.DefaultMathTransformFactory;
+import org.geotools.referencing.operation.DefaultOperation;
+import org.geotools.referencing.operation.DefaultOperationMethod;
+import org.geotools.referencing.operation.transform.AbstractMathTransform;
+import org.geotools.referencing.operation.transform.AffineTransform2D;
+import org.geotools.util.SimpleInternationalString;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.CoordinateOperationAuthorityFactory;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.util.InternationalString;
+
+/**
+ * A {@link CoordinateOperationAuthorityFactory} backed by a properties file.
+ * Allows custom transform definitions across two CRSs, expressed as WKT math transforms.
+ * Entries in the properties file take this format:
+ * <pre>
+ * [source crs code],[target crs code]=[WKT math transform]
+ * </pre>
+ * Examples:
+ * <pre>
+ * 4230,4258=PARAM_MT["NTv2", PARAMETER["Latitude and longitude difference file", "100800401.gsb"]]
+ * 23031,25831=PARAM_MT["Similarity transformation", \
+ * PARAMETER["Ordinate 1 of evaluation point in target CRS", -129.549], \
+ * PARAMETER["Ordinate 2 of evaluation point in target CRS", -208.185], \
+ * PARAMETER["Scale difference", 1.0000015504], \
+ * PARAMETER["Rotation angle of source coordinate reference system axes", 1.56504]]
+ * </pre>
+ * For more compact definitions, parameter names can be replaced by their corresponding EPSG codes.
+ * Following examples are the same as former ones:
+ * <pre>
+ * 4230,4258=PARAM_MT["9615", PARAMETER["8656", "100800401.gsb"]]
+ * 23031,25831=PARAM_MT["9621", \
+ * PARAMETER["8621", -129.549], \
+ * PARAMETER["8622", -208.185], \
+ * PARAMETER["8611", 1.0000015504], \
+ * PARAMETER["8614", 1.56504]]
+ * </pre>
+ * References:
+ * <p>
+ * See <a href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html">
+ * <cite>Well-Known Text format</cite></a> for math transform syntax.
+ * Visit the <a href="http://www.epsg-registry.org/"> <cite>EPSG Geodetic Parameter Registry</cite>
+ * </a> for EPSG parameter codes and values.
+ * <p>
+ * Note that invertible transforms will be used in both directions.
+ * <p>
+ * This factory doesn't cache any result. Any call to a {@code createFoo} method will trig a new
+ * WKT parsing. For caching, this factory should be wrapped in some buffered factory like
+ * {@link BufferedAuthorityFactory}.
+ *
+ * @source $URL$
+ * @version $Id$
+ * @author Oscar Fonts
+ */
+public class PropertyCoordinateOperationAuthorityFactory extends
+ DirectAuthorityFactory implements CoordinateOperationAuthorityFactory {
+
+ /**
+ * The authority for this factory.
+ */
+ private final Citation authority;
+
+ /**
+ * The properties object for our properties file. Keys are CRS code pairs
+ * separated by a comma. The associated value is a WKT string for the Math
+ * Transform. See {@link PropertyCoordinateOperationAuthorityFactory}.
+ */
+ private final Properties definitions = new Properties();
+
+ /**
+ * An unmodifiable view of the authority keys. This view is always up to date
+ * even if entries are added or removed in the {@linkplain #definitions} map.
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private final Set<String> codes = Collections.unmodifiableSet((Set) definitions.keySet());
+
+ /**
+ * Creates a factory for the specified authority from the specified file.
+ *
+ * @param factories The underlying factories used for objects creation.
+ * @param authority The organization or party responsible for definition and maintenance of
+ * the database.
+ * @param definitions URL to the definition file.
+ * @throws IOException if the definitions can't be read.
+ */
+ public PropertyCoordinateOperationAuthorityFactory(
+ final ReferencingFactoryContainer factories,
+ final Citation authority,
+ final URL definitions)
+ throws IOException
+ {
+ // Set priority low
+ super(factories, MINIMUM_PRIORITY + 10);
+
+ // Set authority
+ this.authority = authority;
+ ensureNonNull("authority", authority);
+
+ // Load properties
+ final InputStream in = definitions.openStream();
+ this.definitions.load(in);
+ in.close();
+ }
+
+ /**
+ * Creates an operation from a single operation code.
+ *
+ * @param code Coded value for operation.
+ * @return The operation for the given code.
+ * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+ * @throws FactoryException if the object creation failed for some other reason.
+ */
+ @Override
+ public CoordinateOperation createCoordinateOperation(String code)
+ throws NoSuchAuthorityCodeException, FactoryException {
+ String[] crsPair = trimAuthority(code).split(",");
+ if (crsPair.length == 2) {
+ Set<CoordinateOperation> coordopset = createFromCoordinateReferenceSystemCodes(
+ trimAuthority(crsPair[0]), trimAuthority(crsPair[1]));
+ if (!coordopset.isEmpty()) {
+ return coordopset.iterator().next();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Creates a {@link CoordinateOperation} from
+ * {@linkplain CoordinateReferenceSystem coordinate reference system} codes.
+ * This method returns a single operation from the properties file.
+ * If operation is invertible, will check also for the inverse one.
+ * If operation not found, it will return an empty set.
+ *
+ * @param sourceCRS Coded value of source coordinate reference system.
+ * @param targetCRS Coded value of target coordinate reference system.
+ * @return The operation from {@code sourceCRS} to {@code targetCRS} (one single element).
+ * @throws NoSuchAuthorityCodeException if a specified code was not found.
+ * @throws FactoryException if the object creation failed for some other reason.
+ */
+ @Override
+ public Set<CoordinateOperation> createFromCoordinateReferenceSystemCodes(
+ String sourceCRS, String targetCRS)
+ throws NoSuchAuthorityCodeException, FactoryException {
+
+ Set<CoordinateOperation> coordops = new HashSet<CoordinateOperation>(1);
+
+ CoordinateOperation coordop = createFromCoordinateReferenceSystemCodes(sourceCRS,
+ targetCRS, false);
+ if (coordop == null) {
+ // Not found. Try to create from the inverse.
+ coordop = createFromCoordinateReferenceSystemCodes(targetCRS, sourceCRS, true);
+ }
+ if (coordop != null) {
+ // Add to set if found.
+ coordops.add(coordop);
+ }
+ return coordops;
+ }
+
+
+ /**
+ * Seeks for a WKT definition in the properties file from a CRS pair, parses it,
+ * and creates the corresponding CoordinateOperation. Returns {@code null}
+ * if something went wrong.
+ * <p>
+ * Will log a WARNING message if a parsing error occurred.
+ *
+ * @param sourceCRS Coded value of source coordinate reference system.
+ * @param targetCRS Coded value of target coordinate reference system.
+ * @param inverse {@code true} to create operation from the inverse definition.
+ * @return The operation from {@code sourceCRS} to {@code targetCRS},
+ * or {@code null} if not found.
+ * @throws NoSuchAuthorityCodeException if a specified code was not found.
+ * @throws FactoryException if the object creation failed for some other reason.
+ */
+ CoordinateOperation createFromCoordinateReferenceSystemCodes(
+ String sourceCRS, String targetCRS, boolean inverse)
+ throws NoSuchAuthorityCodeException, FactoryException {
+
+ // Get WKT definition from properties
+ sourceCRS = trimAuthority(sourceCRS);
+ targetCRS = trimAuthority(targetCRS);
+ String id = sourceCRS+","+targetCRS;
+ String WKT = definitions.getProperty(id);
+ if(WKT == null) {
+ // No definition found.
+ return null;
+ }
+
+ // Create MathTransform from WKT
+ MathTransform mt = null;
+ try {
+ mt = factories.getMathTransformFactory().createFromWKT(WKT);
+ } catch (FactoryException e) {
+ // Probably malformed WKT.
+ LOGGER.warning("Error creating transformation: " + WKT);
+ return null;
+ }
+
+ // Create the CRS definitions
+ String s = this.authority.getIdentifiers().iterator().next().getCode();
+ CoordinateReferenceSystem source = CRS.decode(s+":"+sourceCRS);
+ CoordinateReferenceSystem target = CRS.decode(s+":"+targetCRS);
+
+ // Need to create a derived MathTransform that will handle axis order and units
+ // as defined in CRS. Had to cast to DefaultMathTransformFactory because
+ // createBaseToDerived is not defined in MathTransformFactory interface (GeoAPI).
+ DefaultMathTransformFactory mtf = (DefaultMathTransformFactory)factories.
+ getMathTransformFactory();
+ MathTransform mt2 = mtf.createBaseToDerived(source, mt, target.getCoordinateSystem());
+
+ // Extract name from the transform, if possible, or use class name.
+ String methodName;
+ try {
+ if (mt instanceof AbstractMathTransform) {
+ methodName = ((AbstractMathTransform)mt).getParameterValues().getDescriptor().getName().getCode();
+ } else if (mt instanceof AffineTransform2D) {
+ methodName = ((AffineTransform2D)mt).getParameterValues().getDescriptor().getName().getCode();
+ } else {
+ methodName = mt.getClass().getSimpleName();
+ }
+ } catch (NullPointerException e) {
+ methodName = mt.getClass().getSimpleName();
+ }
+ Map<String, String> props = new HashMap<String, String>();
+ props.put("name", methodName);
+
+ // Create the OperationMethod
+ OperationMethod method = new DefaultOperationMethod(props,
+ mt2.getSourceDimensions(), mt2.getTargetDimensions(), null);
+
+ // Finally create CoordinateOperation
+ CoordinateOperation coordop = null;
+ if (!inverse) { // Direct operation
+ props.put("name", sourceCRS + " \u21E8 " + targetCRS);
+ coordop = DefaultOperation.create(props, source, target,
+ mt2, method, CoordinateOperation.class);
+ } else { // Inverse operation
+ try {
+ props.put("name", targetCRS + " \u21E8 " + sourceCRS);
+ coordop = DefaultOperation.create(props, target, source,
+ mt2.inverse(), method, CoordinateOperation.class);
+ } catch (NoninvertibleTransformException e) {
+ return null;
+ }
+ }
+ return coordop;
+ }
+
+ /**
+ * Returns the set of authority codes of the given type.
+ * Only CoordinateOperation.class is accepted as type.
+ *
+ * This factory will not filter codes for its subclasses.
+ *
+ * @param type The CoordinateOperation type (or null, same effect).
+ * @return All of available authority codes, or an empty set.
+ */
+ @Override
+ public Set<String> getAuthorityCodes(Class<? extends IdentifiedObject> type) {
+ if (type==null || type.isAssignableFrom(CoordinateOperation.class)) {
+ return codes;
+ } else {
+ return Collections.emptySet();
+ }
+ }
+
+ /**
+ * Gets a description of the object corresponding to a code.
+ *
+ * @param code Value allocated by authority.
+ * @return A description of the object, or {@code null} if the object
+ * corresponding to the specified {@code code} has no description.
+ * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+ * @throws FactoryException if the query failed for some other reason.
+ */
+ @Override
+ public InternationalString getDescriptionText(String code)
+ throws NoSuchAuthorityCodeException, FactoryException {
+
+ final String wkt = definitions.getProperty(trimAuthority(code));
+
+ if (wkt == null) {
+ throw noSuchAuthorityCode(IdentifiedObject.class, code);
+ }
+
+ // The first string literal in WKT will be considered the description text.
+ int start = wkt.indexOf('"');
+ if (start >= 0) {
+ final int end = wkt.indexOf('"', ++start);
+ if (end >= 0) {
+ return new SimpleInternationalString(wkt.substring(start, end).trim());
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the organization or party responsible for definition and maintenance of the
+ * database.
+ */
+ @Override
+ public Citation getAuthority() {
+ return authority;
+ }
+}
Added: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/CoordinateOperationFactoryUsingWKT.java
===================================================================
--- trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/CoordinateOperationFactoryUsingWKT.java (rev 0)
+++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/CoordinateOperationFactoryUsingWKT.java 2012-05-06 10:24:21 UTC (rev 38703)
@@ -0,0 +1,329 @@
+/*
+ * GeoTools - The Open Source Java GIS Toolkit
+ * http://geotools.org
+ *
+ * (C) 2002-2012, 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.referencing.factory.epsg;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+
+import org.geotools.factory.GeoTools;
+import org.geotools.factory.Hints;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.referencing.ReferencingFactoryFinder;
+import org.geotools.referencing.factory.AbstractAuthorityFactory;
+import org.geotools.referencing.factory.DeferredAuthorityFactory;
+import org.geotools.referencing.factory.FactoryNotFoundException;
+import org.geotools.referencing.factory.PropertyCoordinateOperationAuthorityFactory;
+import org.geotools.referencing.factory.ReferencingFactoryContainer;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.LoggingKeys;
+import org.geotools.resources.i18n.Loggings;
+import org.geotools.util.logging.Logging;
+import org.opengis.metadata.Identifier;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.CoordinateOperationAuthorityFactory;
+
+/**
+ * Authority factory that holds user-defined
+ * {@linkplain CoordinateOperation Coordinate Operations}.
+ * <p>
+ * This factory can be used as a replacement for Coordinate Operations when there is no access
+ * to a complete EPSG database. Or can be used to override the coordinate operations defined in
+ * EPSG if assigned a higher priority.
+ * <p>
+ * The Coordinate Operations are defined as <cite>Well Known Text</cite> math transforms (see
+ * {@link PropertyCoordinateOperationAuthorityFactory} for format specification and examples).
+ * <p>
+ * Property file name is {@value #FILENAME}, and its possible locations are described
+ * {@linkplain #FILENAME here}. If no property file is found, the factory won't be activated.
+ * <p>
+ * If an operation is not found in the properties file, this factory will delegate
+ * creation on a fallback factory. The fallback factory is the next registered
+ * {@link CoordinateOperationAuthorityFactory} after this one in the
+ * {@linkplain org.geotools.factory.AbstractFactory#priority priority} chain.
+ *
+ * @source $URL$
+ * @version $Id$
+ * @author Oscar Fonts
+ */
+public class CoordinateOperationFactoryUsingWKT extends DeferredAuthorityFactory
+ implements CoordinateOperationAuthorityFactory {
+ /**
+ * The authority. Will be created only when first needed.
+ *
+ * @see #getAuthority
+ */
+ protected Citation authority;
+
+ /**
+ * The default filename to read. The default {@code FactoryUsingWKT} implementation will
+ * search for the first occurence of this file in the following places:
+ * <p>
+ * <ul>
+ * <li>In the directory specified by the
+ * {@value org.geotools.factory.GeoTools#CRS_AUTHORITY_EXTRA_DIRECTORY}
+ * system property.</li>
+ * <li>In every {@code org/geotools/referencing/factory/espg} directories found on the
+ * classpath.</li>
+ * </ul>
+ * <p>
+ *
+ * @see #getDefinitionsURL
+ */
+ public static final String FILENAME = "epsg_operations.properties";
+
+ /**
+ * Priority for this factory
+ */
+ public static final int PRIORITY = NORMAL_PRIORITY - 20;
+
+ /**
+ * The factories to be given to the backing store.
+ */
+ protected final ReferencingFactoryContainer factories;
+
+ /**
+ * Directory scanned for extra definitions.
+ */
+ protected final String directory;
+
+ /**
+ * An alternate factory to be used when the primary one doesn't find an operation
+ */
+ protected CoordinateOperationAuthorityFactory fallbackAuthorityFactory = null;
+
+ /**
+ * Just a flag not to search more than once
+ */
+ protected boolean fallbackAuthorityFactorySearched = false;
+
+ /**
+ * Constructs an authority factory using the default set of factories.
+ */
+ public CoordinateOperationFactoryUsingWKT() {
+ this(null, PRIORITY);
+ }
+
+ /**
+ * Constructs an authority factory using a set of factories created from the specified hints.
+ */
+ public CoordinateOperationFactoryUsingWKT(Hints userHints) {
+ this(userHints, PRIORITY);
+ }
+
+ /**
+ * Constructs an authority factory using the specified hints and priority.
+ */
+ protected CoordinateOperationFactoryUsingWKT(final Hints userHints, final int priority) {
+ super(userHints, priority);
+ factories = ReferencingFactoryContainer.instance(userHints);
+
+ // Search for user CRS_AUTHORITY_EXTRA_DIRECTORY hint, or use system default value.
+ Object directoryHint = null;
+ if (userHints != null && userHints.get(Hints.CRS_AUTHORITY_EXTRA_DIRECTORY) != null) {
+ directoryHint = userHints.get(Hints.CRS_AUTHORITY_EXTRA_DIRECTORY);
+ } else if (Hints.getSystemDefault(Hints.CRS_AUTHORITY_EXTRA_DIRECTORY) != null) {
+ directoryHint = Hints.getSystemDefault(Hints.CRS_AUTHORITY_EXTRA_DIRECTORY);
+ }
+ if (directoryHint != null) {
+ directory = directoryHint.toString();
+ hints.put(Hints.CRS_AUTHORITY_EXTRA_DIRECTORY, directory);
+ } else {
+ directory = null;
+ }
+
+ }
+
+ public synchronized Citation getAuthority() {
+ if (authority == null) {
+ authority = Citations.EPSG;
+ }
+ return authority;
+ }
+
+ /**
+ * Creates the backing store authority factory.
+ *
+ * @return The backing store to uses in {@code createXXX(...)} methods.
+ * @throws FactoryNotFoundException if the {@code properties} file has not been found.
+ * @throws FactoryException if the constructor failed to find or read the file.
+ * This exception usually has an {@link IOException} as its cause.
+ */
+ protected AbstractAuthorityFactory createBackingStore() throws FactoryException {
+ try {
+ URL url = getDefinitionsURL();
+ if (url == null) {
+ throw new FactoryNotFoundException(Errors.format(
+ ErrorKeys.FILE_DOES_NOT_EXIST_$1, FILENAME));
+ }
+ final Iterator<? extends Identifier> ids = getAuthority().getIdentifiers().iterator();
+ final String authority = ids.hasNext() ? ids.next().getCode() : "EPSG";
+ final LogRecord record = Loggings.format(Level.CONFIG,
+ LoggingKeys.USING_FILE_AS_FACTORY_$2, url.getPath(), authority);
+ record.setLoggerName(LOGGER.getName());
+ LOGGER.log(record);
+ return new PropertyCoordinateOperationAuthorityFactory(factories, this.getAuthority(), url);
+ } catch (IOException exception) {
+ throw new FactoryException(Errors.format(ErrorKeys.CANT_READ_$1, FILENAME), exception);
+ }
+ }
+
+ /**
+ * Returns the URL to the property file that contains Operation definitions.
+ * The default implementation performs the following search path:
+ * <ul>
+ * <li>If a value is set for the {@value GeoTools#CRS_AUTHORITY_EXTRA_DIRECTORY} system property key,
+ * then the {@value #FILENAME} file will be searched in this directory.</li>
+ * <li>If no value is set for the above-cited system property, or if no {@value #FILENAME}
+ * file was found in that directory, then the first {@value #FILENAME} file found in
+ * any {@code org/geotools/referencing/factory/epsg} directory on the classpath will
+ * be used.</li>
+ * <li>If no file was found on the classpath neither, then this factory will be disabled.</li>
+ * </ul>
+ *
+ * @return The URL, or {@code null} if none.
+ */
+ protected URL getDefinitionsURL() {
+ try {
+ if (directory != null) {
+ final File file = new File(directory, FILENAME);
+ if (file.isFile()) {
+ return file.toURI().toURL(); // TODO
+ }
+ }
+ } catch (SecurityException exception) {
+ Logging.unexpectedException(LOGGER, exception);
+ } catch (MalformedURLException exception) {
+ Logging.unexpectedException(LOGGER, exception);
+ }
+ return this.getClass().getResource(FILENAME);
+ }
+
+ /**
+ * Creates operations from {@linkplain CoordinateReferenceSystem coordinate reference system}
+ * codes.
+ *
+ * This method searches in the {@linkplain #FILENAME properties file} for operations.
+ *
+ * If not found there, it will create operations from a fallback factory (see
+ * {@link #getFallbackAuthorityFactory}).
+ *
+ * @param sourceCRS Coded value of source coordinate reference system.
+ * @param targetCRS Coded value of target coordinate reference system.
+ * @return The operations from {@code sourceCRS} to {@code targetCRS}.
+ * @throws NoSuchAuthorityCodeException if a specified code was not found.
+ * @throws FactoryException if the object creation failed for some other reason.
+ */
+ @Override
+ public Set<CoordinateOperation> createFromCoordinateReferenceSystemCodes(
+ String sourceCRS, String targetCRS) throws NoSuchAuthorityCodeException, FactoryException {
+ Set<CoordinateOperation> coordops = super.createFromCoordinateReferenceSystemCodes(sourceCRS, targetCRS);
+ if (coordops.isEmpty()) {
+ // If not found, delegate to the fallback factory.
+ CoordinateOperationAuthorityFactory fallback = getFallbackAuthorityFactory();
+ if (fallback != null) {
+ coordops = fallback.createFromCoordinateReferenceSystemCodes(sourceCRS, targetCRS);
+ }
+ }
+ return coordops;
+ }
+
+ /**
+ * Creates an operation from a single operation code.
+ *
+ * This method searches in the {@linkplain #FILENAME properties file} for operations.
+ *
+ * If not found there, it will create operations from a fallback factory (see
+ * {@link #getFallbackAuthorityFactory}).
+ *
+ * @param code Coded value for operation.
+ * @return The operation from {@code sourceCRS} to {@code targetCRS}.
+ * @throws NoSuchAuthorityCodeException if a specified code was not found.
+ * @throws FactoryException if the object creation failed for some other reason.
+ */
+ public CoordinateOperation createCoordinateOperation(String code)
+ throws NoSuchAuthorityCodeException, FactoryException {
+ CoordinateOperation coordop = super.createCoordinateOperation(code);
+ if (coordop == null) {
+ CoordinateOperationAuthorityFactory fallback = getFallbackAuthorityFactory();
+ if (fallback != null) {
+ coordop = fallback.createCoordinateOperation(code);
+ }
+ }
+ return coordop;
+ }
+
+ /**
+ * Gets the next available {@link CoordinateOperationAuthorityFactory}
+ * in the priority list.
+ *
+ * @return the alternative CoordinateOperationAuthorityFactory.
+ * @throws NoSuchAuthorityCodeException if a specified code was not found.
+ * @throws FactoryException if the object creation failed for some other reason.
+ */
+ protected CoordinateOperationAuthorityFactory getFallbackAuthorityFactory()
+ throws NoSuchAuthorityCodeException, FactoryException {
+
+ if(!fallbackAuthorityFactorySearched) { // Search once
+ CoordinateOperationAuthorityFactory candidate = null;
+
+ // These hints are to prevent infinite recursion when called
+ // from OrderedAxisAuthorityFactory. See "noForce(Hints)"
+ // from AuthorityBackedFactory.
+ // See also: http://jira.codehaus.org/browse/GEOT-1161
+ Hints h = new Hints();
+ h.put(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.FALSE);
+ h.put(Hints.FORCE_STANDARD_AXIS_DIRECTIONS, Boolean.FALSE);
+ h.put(Hints.FORCE_STANDARD_AXIS_UNITS, Boolean.FALSE);
+
+ Set<CoordinateOperationAuthorityFactory> factories = ReferencingFactoryFinder.
+ getCoordinateOperationAuthorityFactories(h);
+ Iterator<CoordinateOperationAuthorityFactory> it = factories.iterator();
+
+ // Skip factories with higher priority than me.
+ while (it.hasNext()) {
+ candidate = it.next();
+ if (candidate == this) {
+ break;
+ }
+ }
+
+ // Get the next one for this same authority
+ while (it.hasNext()) {
+ candidate = it.next();
+ if (!(candidate instanceof CoordinateOperationFactoryUsingWKT)
+ && candidate.getAuthority().getTitle().equals(this.getAuthority().getTitle())) {
+ fallbackAuthorityFactory = candidate;
+ break;
+ }
+ }
+ fallbackAuthorityFactorySearched = true;
+ }
+
+ return fallbackAuthorityFactory;
+ }
+}
\ No newline at end of file
Modified: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/wkt/MathTransformParser.java
===================================================================
--- trunk/modules/library/referencing/src/main/java/org/geotools/referencing/wkt/MathTransformParser.java 2012-05-04 15:22:05 UTC (rev 38702)
+++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/wkt/MathTransformParser.java 2012-05-06 10:24:21 UTC (rev 38703)
@@ -16,6 +16,7 @@
*/
package org.geotools.referencing.wkt;
+import java.net.URI;
import java.text.ParseException;
import java.text.ParsePosition;
@@ -184,6 +185,8 @@
parameter.setValue(param.pullInteger("value"));
} else if (Double.class.equals(type)) {
parameter.setValue(param.pullDouble("value"));
+ } else if (URI.class.equals(type)){
+ parameter.setValue(URI.create(param.pullString("value")));
} else {
parameter.setValue(param.pullString("value"));
}
Modified: trunk/modules/library/referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.CoordinateOperationAuthorityFactory
===================================================================
--- trunk/modules/library/referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.CoordinateOperationAuthorityFactory 2012-05-04 15:22:05 UTC (rev 38702)
+++ trunk/modules/library/referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.CoordinateOperationAuthorityFactory 2012-05-06 10:24:21 UTC (rev 38703)
@@ -1,3 +1,4 @@
+org.geotools.referencing.factory.epsg.CoordinateOperationFactoryUsingWKT
org.geotools.referencing.factory.epsg.DefaultFactory
org.geotools.referencing.factory.epsg.LongitudeFirstFactory
org.geotools.referencing.factory.URN_AuthorityFactory
Added: trunk/modules/library/referencing/src/test/java/org/geotools/referencing/factory/epsg/CoordinateOperationFactoryUsingWKTTest.java
===================================================================
--- trunk/modules/library/referencing/src/test/java/org/geotools/referencing/factory/epsg/CoordinateOperationFactoryUsingWKTTest.java (rev 0)
+++ trunk/modules/library/referencing/src/test/java/org/geotools/referencing/factory/epsg/CoordinateOperationFactoryUsingWKTTest.java 2012-05-06 10:24:21 UTC (rev 38703)
@@ -0,0 +1,201 @@
+/*
+ * GeoTools - The Open Source Java GIS Toolkit
+ * http://geotools.org
+ *
+ * (C) 2002-2012, 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.referencing.factory.epsg;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.util.Properties;
+import java.util.Set;
+
+import org.geotools.factory.AbstractFactory;
+import org.geotools.factory.Hints;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.referencing.CRS;
+import org.geotools.referencing.ReferencingFactoryFinder;
+import org.junit.Before;
+import org.junit.Test;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+
+/**
+ * Tests the {@link testCoordinateOperationFactoryUsingWKT} public methods.
+ *
+ * @author Oscar Fonts
+ */
+public class CoordinateOperationFactoryUsingWKTTest {
+
+ CoordinateOperationFactoryUsingWKT factory;
+
+ private static final String DEFINITIONS_FILE_NAME = "epsg_operations.properties";
+ private static Properties properties;
+
+ private static final String SOURCE_CRS = "EPSG:TEST1";
+ private static final String TARGET_CRS = "EPSG:TEST2";
+ private static final String CRS_PAIR = SOURCE_CRS + "," + TARGET_CRS;
+ private static final String INVERSE_CRS_PAIR = TARGET_CRS + "," + SOURCE_CRS;
+ private static final String INVALID_CRS = "nonexistent";
+
+ private static final double[] SRC_TEST_POINT = {3.084896111, 39.592654167};
+ private static final double[] DST_TEST_POINT = {3.0844689951999427, 39.594235744481225};
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Before
+ public void setUp() throws Exception {
+ ReferencingFactoryFinder.addAuthorityFactory(
+ new FactoryUsingWKT(null, AbstractFactory.MAXIMUM_PRIORITY));
+
+ factory = (CoordinateOperationFactoryUsingWKT) ReferencingFactoryFinder.
+ getCoordinateOperationAuthorityFactory("EPSG",
+ new Hints(Hints.COORDINATE_OPERATION_AUTHORITY_FACTORY,
+ CoordinateOperationFactoryUsingWKT.class));
+
+ // Read definitions
+ properties = new Properties();
+ properties.load(this.getClass().getResourceAsStream(DEFINITIONS_FILE_NAME));
+ }
+
+ /**
+ * @throws Exception
+ */
+ @Test
+ public void testExtraDirectoryHint() throws Exception {
+ Hints hints = new Hints(Hints.COORDINATE_OPERATION_AUTHORITY_FACTORY,
+ CoordinateOperationFactoryUsingWKT.class);
+ try {
+ hints.put(Hints.CRS_AUTHORITY_EXTRA_DIRECTORY, "invalid");
+ fail("Should of been tossed out as an invalid hint");
+ }
+ catch (IllegalArgumentException expected) {
+ // This is the expected exception.
+ }
+ String directory = new File(".").getAbsolutePath();
+ hints = new Hints(Hints.COORDINATE_OPERATION_AUTHORITY_FACTORY,
+ CoordinateOperationFactoryUsingWKT.class);
+ hints.put(Hints.CRS_AUTHORITY_EXTRA_DIRECTORY, directory);
+
+ CoordinateOperationFactoryUsingWKT fact = (CoordinateOperationFactoryUsingWKT)
+ ReferencingFactoryFinder.getCoordinateOperationAuthorityFactory("EPSG",
+ new Hints(Hints.COORDINATE_OPERATION_AUTHORITY_FACTORY,
+ CoordinateOperationFactoryUsingWKT.class));
+
+ // BTW testing the inverse construction
+ CoordinateOperation co = fact.createCoordinateOperation(INVERSE_CRS_PAIR);
+ CoordinateReferenceSystem crs = CRS.decode(TARGET_CRS);
+ assertSame(crs, co.getSourceCRS());
+ crs = CRS.decode(SOURCE_CRS);
+ assertSame(crs, co.getTargetCRS());
+
+ assertTrue(co.getMathTransform() instanceof MathTransform);
+ double[] p = new double[2];
+ co.getMathTransform().transform(DST_TEST_POINT, 0, p, 0, 1);
+ assertEquals(p[0], SRC_TEST_POINT[0], 1e-8);
+ assertEquals(p[1], SRC_TEST_POINT[1], 1e-8);
+ }
+
+ /**
+ * Test method for {@link CoordinateOperationFactoryUsingWKT#getAuthority}.
+ */
+ @Test
+ public void testGetAuthority() {
+ assertTrue(factory.getAuthority().equals(Citations.EPSG));
+ }
+
+ /**
+ * Test method for {@link CoordinateOperationFactoryUsingWKT#createCoordinateOperation}.
+ * @throws TransformException
+ */
+ @Test
+ public void testCreateCoordinateOperation() throws TransformException {
+
+ try {
+ assertNull(factory.createCoordinateOperation(INVALID_CRS));
+ } catch (FactoryException e) {
+ fail(factory.getClass().getSimpleName() + " threw a FactoryException when requesting"
+ + "a nonexistent operation. Instead, a NoSuchAuthorityCodeException was expected.");
+ }
+
+ try {
+ // Test CoordinateOperation
+ CoordinateOperation co = factory.createCoordinateOperation(CRS_PAIR);
+ assertNotNull(co);
+
+ // Test CRSs
+ CoordinateReferenceSystem crs = CRS.decode(SOURCE_CRS);
+ assertSame(crs, co.getSourceCRS());
+ crs = CRS.decode(TARGET_CRS);
+ assertSame(crs, co.getTargetCRS());
+
+ // Test MathTransform
+ assertTrue(co.getMathTransform() instanceof MathTransform);
+ double[] p = new double[2];
+ co.getMathTransform().transform(SRC_TEST_POINT, 0, p, 0, 1);
+ assertEquals(p[0], DST_TEST_POINT[0], 1e-8);
+ assertEquals(p[1], DST_TEST_POINT[1], 1e-8);
+ } catch (FactoryException e) {
+ fail(factory.getClass().getSimpleName() + " threw a FactoryException when creating" +
+ " coordinate operation from an existing code.");
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link CoordinateOperationFactoryUsingWKT#createFromCoordinateReferenceSystemCodes}.
+ * @throws TransformException
+ */
+ @Test
+ public void testCreateFromCoordinateReferenceSystemCodes() throws TransformException {
+ try {
+ Set<CoordinateOperation> cos = factory.createFromCoordinateReferenceSystemCodes(
+ INVALID_CRS, INVALID_CRS);
+ assertTrue(cos.isEmpty());
+ } catch (FactoryException e) {
+ fail(factory.getClass().getSimpleName() + " threw a FactoryException when requesting"
+ + "a nonexistent operation. Instead, a NoSuchAuthorityCodeException was expected.");
+ }
+
+ try {
+ // Test CoordinateOperation
+ Set<CoordinateOperation> cos = factory.createFromCoordinateReferenceSystemCodes(SOURCE_CRS, TARGET_CRS);
+ assertTrue(cos.size() == 1);
+ CoordinateOperation co = cos.iterator().next();
+ assertNotNull(co);
+
+ // Test CRSs
+ CoordinateReferenceSystem crs = CRS.decode(SOURCE_CRS);
+ assertSame(crs, co.getSourceCRS());
+ crs = CRS.decode(TARGET_CRS);
+ assertSame(crs, co.getTargetCRS());
+
+ // Test MathTransform
+ assertTrue(co.getMathTransform() instanceof MathTransform);
+ double[] p = new double[2];
+ co.getMathTransform().transform(SRC_TEST_POINT, 0, p, 0, 1);
+ assertEquals(p[0], DST_TEST_POINT[0], 1e-8);
+ assertEquals(p[1], DST_TEST_POINT[1], 1e-8);
+ } catch (FactoryException e) {
+ fail(factory.getClass().getSimpleName() + " threw a FactoryException when creating" +
+ " coordinate operation from an existing code.");
+ }
+ }
+}
Modified: trunk/modules/library/referencing/src/test/resources/org/geotools/referencing/factory/epsg/epsg.properties
===================================================================
--- trunk/modules/library/referencing/src/test/resources/org/geotools/referencing/factory/epsg/epsg.properties 2012-05-04 15:22:05 UTC (rev 38702)
+++ trunk/modules/library/referencing/src/test/resources/org/geotools/referencing/factory/epsg/epsg.properties 2012-05-06 10:24:21 UTC (rev 38703)
@@ -5,3 +5,24 @@
#
42101=PROJCS["WGS 84 / LCC Canada",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-95.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",49.0],PARAMETER["standard_parallel_2",77.0],PARAMETER["false_northing",-8000000.0],UNIT["Meter",1]]
+
+# These are used in CoordinateOperationFactoryUsingWKTTest
+TEST1=GEOGCS["ED50", \
+ DATUM["European Datum 1950", \
+ SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], \
+ TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], \
+ AUTHORITY["EPSG","6230"]], \
+ PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], \
+ UNIT["degree", 0.017453292519943295], \
+ AXIS["Geodetic latitude", NORTH], \
+ AXIS["Geodetic longitude", EAST], \
+ AUTHORITY["EPSG","4230"]]
+TEST2=GEOGCS["WGS 84", \
+ DATUM["World Geodetic System 1984", \
+ SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], \
+ AUTHORITY["EPSG","6326"]], \
+ PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], \
+ UNIT["degree", 0.017453292519943295], \
+ AXIS["Geodetic latitude", NORTH], \
+ AXIS["Geodetic longitude", EAST], \
+ AUTHORITY["EPSG","4326"]]
Added: trunk/modules/library/referencing/src/test/resources/org/geotools/referencing/factory/epsg/epsg_operations.properties
===================================================================
--- trunk/modules/library/referencing/src/test/resources/org/geotools/referencing/factory/epsg/epsg_operations.properties (rev 0)
+++ trunk/modules/library/referencing/src/test/resources/org/geotools/referencing/factory/epsg/epsg_operations.properties 2012-05-06 10:24:21 UTC (rev 38703)
@@ -0,0 +1,13 @@
+# Data used in CoordinateOperationFactoryUsingWKTTest
+TEST1,TEST2=CONCAT_MT[ \
+ PARAM_MT["Ellipsoid_To_Geocentric", \
+ PARAMETER["dim", 2], \
+ PARAMETER["semi_major", 6378388.0], \
+ PARAMETER["semi_minor", 6356911.9461279465]], \
+ PARAM_MT["Position Vector transformation (geog2D domain)", PARAMETER["dx", 1], PARAMETER["dy", 2], PARAMETER["dz", 3], PARAMETER["ex", 4], PARAMETER["ey", 5], PARAMETER["ez", 6], PARAMETER["ppm", 7]], \
+ PARAM_MT["Geocentric_To_Ellipsoid", \
+ PARAMETER["dim", 2], \
+ PARAMETER["semi_major", 6378137.0], \
+ PARAMETER["semi_minor", 6356752.314245179]] \
+ ]
+#4230,4258=PARAM_MT["NTv2", PARAMETER["Latitude and longitude difference file", "100800401.gsb"]]
Modified: trunk/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/factory/URN_EPSG_Test.java
===================================================================
--- trunk/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/factory/URN_EPSG_Test.java 2012-05-04 15:22:05 UTC (rev 38702)
+++ trunk/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/factory/URN_EPSG_Test.java 2012-05-06 10:24:21 UTC (rev 38703)
@@ -108,7 +108,7 @@
assertSame(expected, test.createCoordinateReferenceSystem("urn:ogc:def:crs:EPSG:6.11:4326"));
assertEquals("6.11", test.lastVersion.toString());
assertEquals("Should use the fallback factory.",
- failureCount + 1, FallbackAuthorityFactory.getFailureCount());
+ failureCount + 2, FallbackAuthorityFactory.getFailureCount());
}
/**
Added: trunk/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/factory/epsg/LongitudeFirstFactoryOverrideTest.java
===================================================================
--- trunk/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/factory/epsg/LongitudeFirstFactoryOverrideTest.java (rev 0)
+++ trunk/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/factory/epsg/LongitudeFirstFactoryOverrideTest.java 2012-05-06 10:24:21 UTC (rev 38703)
@@ -0,0 +1,135 @@
+/*
+ * GeoTools - The Open Source Java GIS Toolkit
+ * http://geotools.org
+ *
+ * (C) 2002-2012, 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.referencing.factory.epsg;
+
+import static org.junit.Assert.*;
+
+import java.util.Properties;
+
+import org.geotools.factory.AbstractFactory;
+import org.geotools.referencing.CRS;
+import org.geotools.referencing.ReferencingFactoryFinder;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.ConcatenatedOperation;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+
+/**
+ * Makes sure the {@link testCoordinateOperationFactoryUsingWKT} is not ignored when
+ * referencing is setup in "Longitude first" mode.
+ *
+ * @author Oscar Fonts
+ * @author Andrea Aime
+ */
+public class LongitudeFirstFactoryOverrideTest {
+
+ private static final String DEFINITIONS_FILE_NAME = "epsg_operations.properties";
+ private static Properties properties;
+
+ private static final String SOURCE_CRS = "EPSG:TEST1";
+ private static final String TARGET_CRS = "EPSG:TEST2";
+
+ private static final double[] SRC_TEST_POINT = {39.592654167, 3.084896111};
+ private static final double[] DST_TEST_POINT = {39.594235744481225, 3.0844689951999427};
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Before
+ public void setUp() throws Exception {
+ // force longitude first mode
+ System.setProperty("org.geotools.referencing.forceXY", "true");
+
+ CRS.reset("all");
+
+ ReferencingFactoryFinder.addAuthorityFactory(
+ new FactoryUsingWKT(null, AbstractFactory.MAXIMUM_PRIORITY));
+
+ ReferencingFactoryFinder.addAuthorityFactory(new CoordinateOperationFactoryUsingWKT(null, AbstractFactory.MAXIMUM_PRIORITY));
+
+ // Read definitions
+ properties = new Properties();
+ properties.load(this.getClass().getResourceAsStream(DEFINITIONS_FILE_NAME));
+ }
+
+ @After
+ public void tearDown() {
+ // unset axis ordering hint
+ System.clearProperty("org.geotools.referencing.forceXY");
+
+ CRS.reset("all");
+ }
+
+
+ /**
+ * Test method for {@link CoordinateOperationFactoryUsingWKT#createCoordinateOperation}.
+ * @throws TransformException
+ */
+ @Test
+ public void testCreateOperationFromCustomCodes() throws Exception {
+ // Test CRSs
+ CoordinateReferenceSystem source = CRS.decode(SOURCE_CRS);
+ CoordinateReferenceSystem target = CRS.decode(TARGET_CRS);
+ MathTransform mt = CRS.findMathTransform(source, target, true);
+
+ // Test MathTransform
+ double[] p = new double[2];
+ mt.transform(SRC_TEST_POINT, 0, p, 0, 1);
+ assertEquals(p[0], DST_TEST_POINT[0], 1e-8);
+ assertEquals(p[1], DST_TEST_POINT[1], 1e-8);
+ }
+
+ /**
+ * Test method for {@link CoordinateOperationFactoryUsingWKT#createCoordinateOperation}.
+ * @throws TransformException
+ */
+ @Test
+ public void testOverrideEPSGOperation() throws Exception {
+ // Test CRSs
+ CoordinateReferenceSystem source = CRS.decode("EPSG:4269");
+ CoordinateReferenceSystem target = CRS.decode("EPSG:4326");
+ MathTransform mt = CRS.findMathTransform(source, target, true);
+
+ // Test MathTransform
+ double[] p = new double[2];
+ mt.transform(SRC_TEST_POINT, 0, p, 0, 1);
+ assertEquals(p[0], DST_TEST_POINT[0], 1e-8);
+ assertEquals(p[1], DST_TEST_POINT[1], 1e-8);
+ }
+
+ /**
+ * Check we are actually using the EPSG database for anything not in override
+ *
+ * @throws TransformException
+ */
+ @Test
+ public void testFallbackOnEPSGDatabase() throws Exception {
+ // Test CRSs
+ CoordinateReferenceSystem source = CRS.decode("EPSG:3003");
+ CoordinateReferenceSystem target = CRS.decode("EPSG:4326");
+ CoordinateOperation co = CRS.getCoordinateOperationFactory(true).createOperation(source, target);
+ ConcatenatedOperation cco = (ConcatenatedOperation) co;
+ // the EPSG one only has two steps, the non EPSG one 4
+ assertEquals(2, cco.getOperations().size());
+ }
+
+
+}
\ No newline at end of file
Added: trunk/modules/plugin/epsg-hsql/src/test/resources/org/geotools/referencing/factory/epsg/epsg.properties
===================================================================
--- trunk/modules/plugin/epsg-hsql/src/test/resources/org/geotools/referencing/factory/epsg/epsg.properties (rev 0)
+++ trunk/modules/plugin/epsg-hsql/src/test/resources/org/geotools/referencing/factory/epsg/epsg.properties 2012-05-06 10:24:21 UTC (rev 38703)
@@ -0,0 +1,20 @@
+#
+# Additional CRS for unit testing FactoryUsingWkt.
+#
+# $Id$
+#
+
+42101=PROJCS["WGS 84 / LCC Canada",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-95.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",49.0],PARAMETER["standard_parallel_2",77.0],PARAMETER["false_northing",-8000000.0],UNIT["Meter",1]]
+
+# These are used in CoordinateOperationFactoryUsingWKTTest
+TEST1=GEOGCS["ED50", \
+ DATUM["European Datum 1950", \
+ SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], \
+ TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52]], \
+ PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], \
+ UNIT["degree", 0.017453292519943295]]
+TEST2=GEOGCS["WGS 84", \
+ DATUM["World Geodetic System 1984", \
+ SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]]], \
+ PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], \
+ UNIT["degree", 0.017453292519943295]]
Added: trunk/modules/plugin/epsg-hsql/src/test/resources/org/geotools/referencing/factory/epsg/epsg_operations.properties
===================================================================
--- trunk/modules/plugin/epsg-hsql/src/test/resources/org/geotools/referencing/factory/epsg/epsg_operations.properties (rev 0)
+++ trunk/modules/plugin/epsg-hsql/src/test/resources/org/geotools/referencing/factory/epsg/epsg_operations.properties 2012-05-06 10:24:21 UTC (rev 38703)
@@ -0,0 +1,24 @@
+# Data used in CoordinateOperationFactoryUsingWKTTest
+TEST1,TEST2=CONCAT_MT[ \
+ PARAM_MT["Ellipsoid_To_Geocentric", \
+ PARAMETER["dim", 2], \
+ PARAMETER["semi_major", 6378388.0], \
+ PARAMETER["semi_minor", 6356911.9461279465]], \
+ PARAM_MT["Position Vector transformation (geog2D domain)", PARAMETER["dx", 1], PARAMETER["dy", 2], PARAMETER["dz", 3], PARAMETER["ex", 4], PARAMETER["ey", 5], PARAMETER["ez", 6], PARAMETER["ppm", 7]], \
+ PARAM_MT["Geocentric_To_Ellipsoid", \
+ PARAMETER["dim", 2], \
+ PARAMETER["semi_major", 6378137.0], \
+ PARAMETER["semi_minor", 6356752.314245179]] \
+ ]
+4269,4326=CONCAT_MT[ \
+ PARAM_MT["Ellipsoid_To_Geocentric", \
+ PARAMETER["dim", 2], \
+ PARAMETER["semi_major", 6378388.0], \
+ PARAMETER["semi_minor", 6356911.9461279465]], \
+ PARAM_MT["Position Vector transformation (geog2D domain)", PARAMETER["dx", 1], PARAMETER["dy", 2], PARAMETER["dz", 3], PARAMETER["ex", 4], PARAMETER["ey", 5], PARAMETER["ez", 6], PARAMETER["ppm", 7]], \
+ PARAM_MT["Geocentric_To_Ellipsoid", \
+ PARAMETER["dim", 2], \
+ PARAMETER["semi_major", 6378137.0], \
+ PARAMETER["semi_minor", 6356752.314245179]] \
+ ]
+#4230,4258=PARAM_MT["NTv2", PARAMETER["Latitude and longitude difference file", "100800401.gsb"]]
|
|
From: <svn...@os...> - 2012-05-04 15:22:16
|
Author: aaime
Date: 2012-05-04 08:22:05 -0700 (Fri, 04 May 2012)
New Revision: 38702
Modified:
trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/response/ExecuteProcessResponse.java
trunk/modules/unsupported/wps/src/test/java/org/geotools/data/wps/OnlineWPSManualRequestTest.java
Log:
[GEOT-4127] WPS client won't report exceptions in case a raw response has been demanded by the client
Modified: trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/response/ExecuteProcessResponse.java
===================================================================
--- trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/response/ExecuteProcessResponse.java 2012-05-03 13:01:36 UTC (rev 38701)
+++ trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/response/ExecuteProcessResponse.java 2012-05-04 15:22:05 UTC (rev 38702)
@@ -76,7 +76,7 @@
// could be gml or other stuff, not necessarily a service exception, we need to check if it's an exception or not
rawContentType = httpResponse.getContentType();
- if(rawContentType.startsWith("text/xml")) {
+ if(rawContentType.matches(".*/xml.*")) {
// make sure we don't throw away info
inputStream = new BufferedInputStream(httpResponse.getResponseStream());
inputStream.mark(8192);
@@ -89,9 +89,8 @@
// get the first tag name
String name = parser.getName();
- String namespace = parser.getNamespace();
inputStream.reset();
- if("ServiceException".equals(name) || "ExecuteResponse".equals(name)) {
+ if("ServiceException".equals(name) || "ExceptionReport".equals(name) || "ExecuteResponse".equals(name)) {
parseDocumentResponse(inputStream);
return;
}
@@ -143,6 +142,10 @@
if (object instanceof ExecuteResponseType)
{
exeResponse = (ExecuteResponseType) object;
+ // in case of exceptions let's be explicit about them
+ if(exeResponse.getStatus() != null && exeResponse.getStatus().getProcessFailed() != null) {
+ excepResponse = exeResponse.getStatus().getProcessFailed().getExceptionReport();
+ }
}
// exception caught on server and returned
else if (object instanceof ExceptionReportType)
Modified: trunk/modules/unsupported/wps/src/test/java/org/geotools/data/wps/OnlineWPSManualRequestTest.java
===================================================================
--- trunk/modules/unsupported/wps/src/test/java/org/geotools/data/wps/OnlineWPSManualRequestTest.java 2012-05-03 13:01:36 UTC (rev 38701)
+++ trunk/modules/unsupported/wps/src/test/java/org/geotools/data/wps/OnlineWPSManualRequestTest.java 2012-05-04 15:22:05 UTC (rev 38702)
@@ -26,6 +26,7 @@
import java.util.List;
import net.opengis.ows11.ExceptionReportType;
+import net.opengis.ows11.ExceptionType;
import net.opengis.wps10.DataType;
import net.opengis.wps10.DocumentOutputDefinitionType;
import net.opengis.wps10.ExecuteResponseType;
@@ -933,4 +934,152 @@
System.out.println(arcgrid);
assertTrue(arcgrid.startsWith(expectedHeader));
}
+
+ /**
+ * Test exception parsing on invalid process request
+ *
+ * @throws ServiceException
+ * @throws IOException
+ * @throws ParseException
+ */
+ public void testInvalidProcess() throws ServiceException, IOException, ParseException
+ {
+
+ // don't run the test if the server is not up
+ if (fixture == null)
+ {
+ return;
+ }
+
+ if (DISABLE)
+ {
+ return;
+ }
+
+ String processIdenLocal = "gs:InvalidProcessName";
+
+ WPSCapabilitiesType capabilities = wps.getCapabilities();
+
+ // get the first process and execute it
+ ProcessOfferingsType processOfferings = capabilities.getProcessOfferings();
+ EList processes = processOfferings.getProcess();
+ // ProcessBriefType process = (ProcessBriefType) processes.get(0);
+
+ // does the server contain the specific process I want
+ boolean found = false;
+ Iterator iterator = processes.iterator();
+ while (iterator.hasNext())
+ {
+ ProcessBriefType process = (ProcessBriefType) iterator.next();
+ if (process.getIdentifier().getValue().equalsIgnoreCase(processIdenLocal))
+ {
+ found = true;
+
+ break;
+ }
+ }
+
+ // exit test if my process doesn't exist on server
+ if (found)
+ {
+ System.out.println("Skipping, gs:InvalidProcessName has been found!");
+ return;
+ }
+
+ // setup a fake call to fake process
+ ExecuteProcessRequest exeRequest = wps.createExecuteProcessRequest();
+ exeRequest.setIdentifier(processIdenLocal);
+ ResponseDocumentType doc = wps.createResponseDocumentType(false, true, true, "result");
+ DocumentOutputDefinitionType odt = (DocumentOutputDefinitionType) doc.getOutput().get(0);
+ odt.setMimeType("application/arcgrid");
+ odt.setAsReference(true);
+ ResponseFormType responseForm = wps.createResponseForm(doc, null);
+ exeRequest.setResponseForm(responseForm);
+
+ // send the request
+ ExecuteProcessResponse response = wps.issueRequest(exeRequest);
+
+ // response should not be null and no exception should occur.
+ assertNotNull(response);
+
+ // we should get an exception
+ ExceptionReportType report = response.getExceptionResponse();
+ assertNotNull(report);
+ ExceptionType exception = (ExceptionType) report.getException().get(0);
+ String errorMessage = exception.getExceptionText().get(0).toString();
+ assertTrue(errorMessage.contains(processIdenLocal));
+ }
+
+ /**
+ * Make sure we get the proper exception report
+ *
+ * @throws ServiceException
+ * @throws IOException
+ * @throws ParseException
+ */
+ public void testInvalidParamsRawOutput() throws ServiceException, IOException, ParseException
+ {
+
+ // don't run the test if the server is not up
+ if (fixture == null)
+ {
+ return;
+ }
+
+ if (DISABLE)
+ {
+ return;
+ }
+
+ String processIdenLocal = "gs:AreaGrid";
+
+ WPSCapabilitiesType capabilities = wps.getCapabilities();
+
+ // get the first process and execute it
+ ProcessOfferingsType processOfferings = capabilities.getProcessOfferings();
+ EList processes = processOfferings.getProcess();
+ // ProcessBriefType process = (ProcessBriefType) processes.get(0);
+
+ // does the server contain the specific process I want
+ boolean found = false;
+ Iterator iterator = processes.iterator();
+ while (iterator.hasNext())
+ {
+ ProcessBriefType process = (ProcessBriefType) iterator.next();
+ if (process.getIdentifier().getValue().equalsIgnoreCase(processIdenLocal))
+ {
+ found = true;
+
+ break;
+ }
+ }
+
+ // exit test if my process doesn't exist on server
+ if (!found)
+ {
+ System.out.println("Skipping, gs:AreaGrid not found!");
+ return;
+ }
+
+ // based on the describeprocess, setup the execute
+ ExecuteProcessRequest exeRequest = wps.createExecuteProcessRequest();
+ exeRequest.setIdentifier(processIdenLocal);
+ // don't send over the inputs
+ OutputDefinitionType rawOutput = wps.createOutputDefinitionType("result");
+ rawOutput.setMimeType("application/arcgrid");
+ ResponseFormType responseForm = wps.createResponseForm(null, rawOutput);
+ exeRequest.setResponseForm(responseForm);
+
+ // send the request
+ ExecuteProcessResponse response = wps.issueRequest(exeRequest);
+
+ // response should not be null and no exception should occur.
+ assertNotNull(response);
+
+ // we should get an exception here too
+ ExceptionReportType report = response.getExceptionResponse();
+ assertNotNull(report);
+ }
+
+
}
|
Author: ang05a
Date: 2012-05-03 06:01:36 -0700 (Thu, 03 May 2012)
New Revision: 38701
Modified:
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/AttributeMapping.java
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/ComplexFeatureConstants.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/NestedAttributeMapping.java
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/AppSchemaDataAccessConfigurator.java
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/AttributeMapping.java
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/XMLConfigDigester.java
trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/TestData.java
trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/AppSchemaDataAccess.xsd
Log:
GEOT-4126: Enable specifying row number in getting sourceExpression for denormalised rows (for timeseries subsetting).
Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/AttributeMapping.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/AttributeMapping.java 2012-05-02 13:20:19 UTC (rev 38700)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/AttributeMapping.java 2012-05-03 13:01:36 UTC (rev 38701)
@@ -63,6 +63,8 @@
private String instancePath;
+ private String sourceIndex;
+
/**
* Creates a new AttributeMapping object.
*
@@ -73,10 +75,10 @@
*/
public AttributeMapping(Expression idExpression, Expression sourceExpression,
StepList targetXPath) {
- this(idExpression, sourceExpression, targetXPath, null, false, null);
+ this(idExpression, sourceExpression, null, targetXPath, null, false, null);
}
- public AttributeMapping(Expression idExpression, Expression sourceExpression,
+ public AttributeMapping(Expression idExpression, Expression sourceExpression, String sourceIndex,
StepList targetXPath, AttributeType targetNodeInstance, boolean isMultiValued,
Map<Name, Expression> clientProperties) {
@@ -86,6 +88,7 @@
if (this.sourceExpression == null) {
this.sourceExpression = Expression.NIL;
}
+ this.sourceIndex = sourceIndex;
this.targetXPath = targetXPath;
this.targetNodeInstance = targetNodeInstance;
this.clientProperties = clientProperties == null ? Collections
@@ -103,6 +106,10 @@
public Expression getSourceExpression() {
return sourceExpression;
}
+
+ public String getSourceIndex() {
+ return sourceIndex;
+ }
public StepList getTargetXPath() {
return targetXPath;
Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/ComplexFeatureConstants.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/ComplexFeatureConstants.java 2012-05-02 13:20:19 UTC (rev 38700)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/ComplexFeatureConstants.java 2012-05-03 13:01:36 UTC (rev 38701)
@@ -85,4 +85,9 @@
* Fake attribute name for simple contents of a complex type, eg. gml:name of gml:CodeType type
*/
public static final Name SIMPLE_CONTENT = new NameImpl(null, "simpleContent");
+
+ /**
+ * Constant to indicate the last row from denormalised rows.
+ */
+ public static final String LAST_INDEX = "LAST";
}
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-05-02 13:20:19 UTC (rev 38700)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/DataAccessMappingFeatureIterator.java 2012-05-03 13:01:36 UTC (rev 38701)
@@ -902,7 +902,17 @@
setAttributeValue(target, null, source, attMapping, null, null, selectedProperties.get(attMapping));
}
} else {
- setAttributeValue(target, null, sources.get(0), attMapping, null, null, selectedProperties.get(attMapping));
+ String indexString = attMapping.getSourceIndex();
+ // if not specified, get the first row by default
+ int index = 0;
+ if (indexString != null) {
+ if (ComplexFeatureConstants.LAST_INDEX.equals(indexString)) {
+ index = sources.size() - 1;
+ } else {
+ index = Integer.parseInt(indexString);
+ }
+ }
+ setAttributeValue(target, null, sources.get(index), attMapping, null, null, selectedProperties.get(attMapping));
// When a feature is not multi-valued but still has multiple rows with the same ID in
// a denormalised table, by default app-schema only takes the first row and ignores
// the rest (see above). The following line is to make sure that the cursors in the
Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/NestedAttributeMapping.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/NestedAttributeMapping.java 2012-05-02 13:20:19 UTC (rev 38700)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/NestedAttributeMapping.java 2012-05-03 13:01:36 UTC (rev 38701)
@@ -127,7 +127,7 @@
StepList targetXPath, boolean isMultiValued, Map<Name, Expression> clientProperties,
Expression sourceElement, StepList sourcePath, NamespaceSupport namespaces)
throws IOException {
- super(idExpression, parentExpression, targetXPath, null, isMultiValued, clientProperties);
+ super(idExpression, parentExpression, null, targetXPath, null, isMultiValued, clientProperties);
this.nestedTargetXPath = sourcePath;
this.nestedFeatureType = sourceElement;
this.filterFac = new FilterFactoryImplNamespaceAware(namespaces);
Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/AppSchemaDataAccessConfigurator.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/AppSchemaDataAccessConfigurator.java 2012-05-02 13:20:19 UTC (rev 38700)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/AppSchemaDataAccessConfigurator.java 2012-05-03 13:01:36 UTC (rev 38701)
@@ -346,8 +346,6 @@
final boolean isMultiValued = attDto.isMultiple();
- final boolean isList = attDto.isList();
-
final Expression idExpression = (idXpath == null) ? parseOgcCqlExpression(idExpr)
: new AttributeExpressionImpl(idXpath, new Hints(
FeaturePropertyAccessorFactory.NAMESPACE_CONTEXT, this.namespaces));
@@ -401,7 +399,7 @@
}
} else {
- attMapping = new AttributeMapping(idExpression, sourceExpression, targetXPathSteps,
+ attMapping = new AttributeMapping(idExpression, sourceExpression, attDto.getSourceIndex(), targetXPathSteps,
expectedInstanceOf, isMultiValued, clientProperties);
}
Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/AttributeMapping.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/AttributeMapping.java 2012-05-02 13:20:19 UTC (rev 38700)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/AttributeMapping.java 2012-05-03 13:01:36 UTC (rev 38701)
@@ -62,6 +62,17 @@
private String sourceExpression;
/**
+ * Expression whose evaluation result in numeric value to indicate row number to extract {@link
+ * this#sourceExpression} from denormalised database rows.
+ *
+ * <p>
+ * At this stage, the expression must be a valid integer, or LAST would work to
+ * get the last dynamic result.
+ * </p>
+ */
+ private String sourceIndex;
+
+ /**
* Label used to refer to an attribute.
*/
private String label;
@@ -162,6 +173,31 @@
}
/**
+ * Returns the expression whose evaluation result in numeric value to indicate row number to extract {@link
+ * this#sourceExpression} from denormalised database rows.
+ *
+ * <p>
+ * At this stage, the expression must be a valid integer, or LAST would work to
+ * get the last dynamic result.
+ * </p>
+ *
+ * @return OGC CQL expression for the attribute value
+ */
+ public String getSourceIndex() {
+ return sourceIndex;
+ }
+
+ /**
+ * Sets the OGC CQL expression index for the attribute value.
+ *
+ * @param sourceIndex
+ * OGC CQL expression index for the attribute value.
+ */
+ public void setSourceIndex(String sourceIndex) {
+ this.sourceIndex = sourceIndex;
+ }
+
+ /**
* Return the input XPath expression
* @return the input XPath expression
*/
Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/XMLConfigDigester.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/XMLConfigDigester.java 2012-05-02 13:20:19 UTC (rev 38700)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/XMLConfigDigester.java 2012-05-03 13:01:36 UTC (rev 38701)
@@ -238,6 +238,9 @@
digester.addCallMethod(attMap + "/sourceExpression/OCQL", "setSourceExpression", 1);
digester.addCallParam(attMap + "/sourceExpression/OCQL", 0);
+
+ digester.addCallMethod(attMap + "/sourceExpression/index", "setSourceIndex", 1);
+ digester.addCallParam(attMap + "/sourceExpression/index", 0);
digester.addCallMethod(attMap + "/idExpression/inputAttribute", "setIdentifierPath", 1);
digester.addCallParam(attMap + "/idExpression/inputAttribute", 0);
Modified: trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/TestData.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/TestData.java 2012-05-02 13:20:19 UTC (rev 38700)
+++ trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/TestData.java 2012-05-03 13:01:36 UTC (rev 38701)
@@ -297,7 +297,7 @@
id = ff.property("id[1]");
source = null;
target = "wq_plus/measurement";
- mappings.add(new AttributeMapping(id, source, XPath
+ mappings.add(new AttributeMapping(id, source, null, XPath
.steps(targetFeature, target, namespaces), null, true, null));
source = ff.property("determinand_description");
Modified: trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/AppSchemaDataAccess.xsd
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/AppSchemaDataAccess.xsd 2012-05-02 13:20:19 UTC (rev 38700)
+++ trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/AppSchemaDataAccess.xsd 2012-05-03 13:01:36 UTC (rev 38701)
@@ -310,7 +310,16 @@
</annotation>
<sequence>
<choice minOccurs="0">
- <element name="OCQL" type="string" />
+ <sequence>
+ <element name="OCQL" type="string" />
+ <element name="index" type="string" minOccurs="0" maxOccurs="1">
+ <annotation>
+ <documentation>
+ <![CDATA[ The index of database row if denormalised. Example of usage is timeseries endPosition that reflects the last timePosition where the timePosition value is dynamic. ]]>
+ </documentation>
+ </annotation>
+ </element>
+ </sequence>
<element name="Expression">
<complexType>
<sequence>
|
|
From: <svn...@os...> - 2012-05-02 13:20:27
|
Author: ang05a
Date: 2012-05-02 06:20:19 -0700 (Wed, 02 May 2012)
New Revision: 38700
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/MappingFeatureIteratorFactory.java
Log:
App-schema isList: subsetting should affect other property values outside the filter properties.
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-05-02 01:23:15 UTC (rev 38699)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/DataAccessMappingFeatureIterator.java 2012-05-02 13:20:19 UTC (rev 38700)
@@ -124,8 +124,6 @@
*/
private Filter listFilter;
- private List<StepList> listFilterProperties;
-
public DataAccessMappingFeatureIterator(AppSchemaDataAccess store, FeatureTypeMapping mapping,
Query query, boolean isFiltered) throws IOException {
this(store, mapping, query, null);
@@ -181,6 +179,24 @@
}
}
}
+ // HACK HACK HACK
+ // evaluate filter that applies to this list as we want a subset
+ // instead of full result
+ // this is a temporary solution for Bureau of Meteorology
+ // requirement for timePositionList
+ if (listFilter != null) {
+ while (exists && !listFilter.evaluate(curSrcFeature)) {
+ // only add to subset if filter matches value
+ if (getSourceFeatureIterator() != null
+ && getSourceFeatureIterator().hasNext()) {
+ this.curSrcFeature = getSourceFeatureIterator().next();
+ exists = true;
+ } else {
+ exists = false;
+ }
+ }
+ }
+ // END OF HACK
} else {
exists = false;
}
@@ -714,8 +730,26 @@
while (getSourceFeatureIterator().hasNext()) {
Feature next = getSourceFeatureIterator().next();
if (extractIdForFeature(next).equals(fId) && checkForeignIdValues(foreignIdValues, next)) {
- features.add(next);
- } else {
+ // HACK HACK HACK
+ // evaluate filter that applies to this list as we want a subset
+ // instead of full result
+ // this is a temporary solution for Bureau of Meteorology
+ // requirement for timePositionList
+ if (listFilter != null) {
+ if (listFilter.evaluate(next)) {
+ features.add(next);
+ }
+ // END OF HACK
+ } else {
+ features.add(next);
+ }
+ // HACK HACK HACK
+ // evaluate filter that applies to this list as we want a subset
+ // instead of full result
+ // this is a temporary solution for Bureau of Meteorology
+ // requirement for timePositionList
+ } else if (listFilter == null || listFilter.evaluate(next)) {
+ // END OF HACK
curSrcFeature = next;
break;
}
@@ -740,6 +774,8 @@
query.setCoordinateSystemReproject(reprojection);
}
}
+
+ Filter fidFilter;
if (mapping.getFeatureIdExpression().equals(Expression.NIL)) {
// no real feature id mapping,
@@ -747,16 +783,30 @@
Set<FeatureId> ids = new HashSet<FeatureId>();
FeatureId featureId = namespaceAwareFilterFactory.featureId(fId);
ids.add(featureId);
- query.setFilter(namespaceAwareFilterFactory.id(ids));
- matchingFeatures = this.mappedSource.getFeatures(query);
+ fidFilter = namespaceAwareFilterFactory.id(ids);
} else {
// in case the expression is wrapped in a function, eg. strConcat
// that's why we don't always filter by id, but do a PropertyIsEqualTo
- query.setFilter(namespaceAwareFilterFactory.equals(mapping.getFeatureIdExpression(),
- namespaceAwareFilterFactory.literal(fId)));
- matchingFeatures = this.mappedSource.getFeatures(query);
+ fidFilter = namespaceAwareFilterFactory.equals(mapping.getFeatureIdExpression(),
+ namespaceAwareFilterFactory.literal(fId));
}
+
+ // HACK HACK HACK
+ // evaluate filter that applies to this list as we want a subset
+ // instead of full result
+ // this is a temporary solution for Bureau of Meteorology
+ // requirement for timePositionList
+ if (listFilter != null) {
+ List<Filter> filters = new ArrayList<Filter>();
+ filters.add(listFilter);
+ filters.add(fidFilter);
+ fidFilter = namespaceAwareFilterFactory.and(filters);
+ }
+ // END OF HACK
+ query.setFilter(fidFilter);
+ matchingFeatures = this.mappedSource.getFeatures(query);
+
FeatureIterator<? extends Feature> iterator = matchingFeatures.features();
List<Feature> features = new ArrayList<Feature>();
@@ -830,24 +880,8 @@
if (sources.size() > 1 && instance != null) {
List<Object> values = new ArrayList<Object>();
Expression sourceExpr = attMapping.getSourceExpression();
- if (listFilter != null
- && listFilterProperties.contains(attMapping.getTargetXPath())) {
- for (Feature source : sources) {
- // HACK HACK HACK
- // evaluate filter that applies to this list as we want a subset
- // instead of full result
- // this is a temporary solution for Bureau of Meteorology
- // requirement for timePositionList
- if (listFilter.evaluate(source)) {
- // only add to subset if filter matches value
- values.add(getValue(sourceExpr, source));
- }
- }
- } else {
- // no filter concerning the list
- for (Feature source : sources) {
- values.add(getValue(sourceExpr, source));
- }
+ for (Feature source : sources) {
+ values.add(getValue(sourceExpr, source));
}
String valueString = StringUtils.join(values.iterator(), " ");
StepList fullPath = attMapping.getTargetXPath();
@@ -975,7 +1009,6 @@
sourceFeatureIterator = null;
sourceFeatures = null;
filteredFeatures = null;
- listFilterProperties = null;
listFilter = null;
//NC - joining nested atts
@@ -1111,9 +1144,5 @@
public void setListFilter(Filter filter) {
listFilter = filter;
- }
-
- public void setListFilterProperties(List<StepList> properties) {
- listFilterProperties = properties;
- }
+ }
}
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-05-02 01:23:15 UTC (rev 38699)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/MappingFeatureIteratorFactory.java 2012-05-02 13:20:19 UTC (rev 38700)
@@ -18,7 +18,6 @@
package org.geotools.data.complex;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
@@ -69,15 +68,15 @@
// Attribute mappings that have isList enabled
private List<AttributeMapping> listMappings;
- // Filter properties that are configured as isList
- private List<StepList> listFilterProperties;
+ // True if the filter has properties that are configured as isList
+ private boolean isListFilter;
private FeatureTypeMapping mappings;
public IsListFilterVisitor(List<AttributeMapping> listMappings, FeatureTypeMapping mappings) {
this.listMappings = listMappings;
this.mappings = mappings;
- listFilterProperties = new ArrayList<StepList>();
+ isListFilter = false;
}
@Override
@@ -91,14 +90,15 @@
targetXpath = mapping.getTargetXPath();
if (targetXpath.equals(simplifiedSteps)) {
// TODO: support feature chaining too?
- listFilterProperties.add(targetXpath);
+ isListFilter = true;
+ return extraData;
}
}
return extraData;
}
- public List<StepList> getListFilterProperties() {
- return listFilterProperties;
+ public boolean isListFilterExists() {
+ return isListFilter;
}
}
@@ -107,23 +107,7 @@
if (mapping instanceof XmlFeatureTypeMapping) {
return new XmlMappingFeatureIterator(store, mapping, query);
- }
-
- // HACK HACK HACK
- // experimental/temporary solution for isList subsetting by filtering
- List<AttributeMapping> listMappings = mapping.getIsListMappings();
- Filter isListFilter = null;
- List<StepList> listFilterProperties = null;
- if (!listMappings.isEmpty()) {
- IsListFilterVisitor listChecker = new IsListFilterVisitor(listMappings, mapping);
- Filter complexFilter = query.getFilter();
- complexFilter.accept(listChecker, null);
- listFilterProperties = listChecker.getListFilterProperties();
- if (!listFilterProperties.isEmpty()) {
- isListFilter = AppSchemaDataAccess.unrollFilter(complexFilter, mapping);
- }
- }
- // END OF HACK
+ }
boolean isJoining = AppSchemaDataAccessConfigurator.isJoining();
@@ -146,6 +130,19 @@
unrolledQuery);
}
} else {
+ // HACK HACK HACK
+ // experimental/temporary solution for isList subsetting by filtering
+ List<AttributeMapping> listMappings = mapping.getIsListMappings();
+ Filter isListFilter = null;
+ if (!listMappings.isEmpty()) {
+ IsListFilterVisitor listChecker = new IsListFilterVisitor(listMappings, mapping);
+ Filter complexFilter = query.getFilter();
+ complexFilter.accept(listChecker, null);
+ if (listChecker.isListFilterExists()) {
+ isListFilter = AppSchemaDataAccess.unrollFilter(complexFilter, mapping);
+ }
+ }
+ // END OF HACK
FeatureSource mappedSource = mapping.getSource();
if (isJoining || mappedSource instanceof JDBCFeatureSource
|| mappedSource instanceof JDBCFeatureStore) {
@@ -169,15 +166,12 @@
iterator = new DataAccessMappingFeatureIterator(store, mapping, query, isFiltered);
// HACK HACK HACK
// experimental/temporary solution for isList subsetting by filtering
- if (isListFilter != null) {
- ((DataAccessMappingFeatureIterator) iterator).setListFilter(isListFilter);
- ((DataAccessMappingFeatureIterator) iterator)
- .setListFilterProperties(listFilterProperties);
- }
+ if (isListFilter == null) {
// END OF HACK
- if (filter != null && filter != Filter.INCLUDE) {
- iterator = new PostFilteringMappingFeatureIterator(iterator, filter,
+ if (filter != null && filter != Filter.INCLUDE) {
+ iterator = new PostFilteringMappingFeatureIterator(iterator, filter,
maxFeatures);
+ }
}
} else if (mappedSource instanceof MappingFeatureSource) {
// web service data access wrapper
@@ -212,17 +206,13 @@
iterator = new DataAccessMappingFeatureIterator(store, mapping, query);
}
}
+ // HACK HACK HACK
+ // experimental/temporary solution for isList subsetting by filtering
+ if (isListFilter != null && iterator instanceof DataAccessMappingFeatureIterator) {
+ ((DataAccessMappingFeatureIterator) iterator).setListFilter(isListFilter);
+ }
+ // END OF HACK
}
-
- // HACK HACK HACK
- // experimental/temporary solution for isList subsetting by filtering
- if (isListFilter != null && iterator instanceof DataAccessMappingFeatureIterator) {
- ((DataAccessMappingFeatureIterator) iterator).setListFilter(isListFilter);
- ((DataAccessMappingFeatureIterator) iterator)
- .setListFilterProperties(listFilterProperties);
- }
- // END OF HACK
-
return iterator;
}
|
|
From: <svn...@os...> - 2012-05-02 01:23:24
|
Author: jive
Date: 2012-05-01 18:23:15 -0700 (Tue, 01 May 2012)
New Revision: 38699
Modified:
trunk/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyAttributeReader.java
trunk/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyAttributeWriter.java
trunk/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyFeatureWriter.java
trunk/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyDataStore2Test.java
trunk/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyDataStoreTest.java
trunk/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyExamples.java
Log:
work on property string encoding
Signed-off-by: Jody Garnett <jod...@gm...>
Modified: trunk/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyAttributeReader.java
===================================================================
--- trunk/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyAttributeReader.java 2012-05-01 18:57:46 UTC (rev 38698)
+++ trunk/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyAttributeReader.java 2012-05-02 01:23:15 UTC (rev 38699)
@@ -4,8 +4,11 @@
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
+import java.util.Arrays;
import java.util.NoSuchElementException;
import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.geotools.data.AttributeReader;
import org.geotools.data.DataSourceException;
@@ -48,14 +51,19 @@
* </p>
*
* <pre>
- * <code>
- * fid4=4||<null> -> Feature( id=2, name="", geom=null )
- * </code>
+ * fid4=4||<null>
* </pre>
+ * <p>
+ * You can use \ to escape a | character, you can also use it to protect newlines::
+ * <pre>
+ * fid4=4|I have a \\|splitting\\| headache|POINT(0,0)
+ * fid5=5|Example of \nmulti-lin text|POINT(1,1)
+ * fid6=6|Second \\
+ * example of multi-line text|POINT(2,2)
+ * </pre>
*
* @author Jody Garnett
*
- *
* @source $URL$
*/
public class PropertyAttributeReader implements AttributeReader {
@@ -183,10 +191,14 @@
if( txt == null ){
break;
}
+ // skip comments
if( txt.startsWith("#") || txt.startsWith("!")){
- continue; // skip content
+ continue;
}
+ // ignore leading white space
txt = trimLeft( txt );
+
+ // handle escaped line feeds used to span multiple lines
if( txt.endsWith("\\")){
buffer.append(txt.substring(0,txt.length()-1) );
buffer.append("\n");
@@ -201,13 +213,30 @@
return null; // there is no line
}
String raw = buffer.toString();
- raw = raw.replace("\\n", "\n" );
- raw = raw.replace("\\r", "\r" );
- raw = raw.replace("\\t", "\t" );
+// String line = decodeString(raw);
+// return line;
return raw;
}
/**
- * Trim leading white space as described Properties.
+ * Used to decode common whitespace chracters and escaped | characters.
+ *
+ * @param txt Origional raw text as stored
+ * @return decoded text as provided for storage
+ * @see PropertyAttributeWriter#encodeString(String)
+ */
+ String decodeString( String txt ){
+ // unpack whitespace constants
+ txt = txt.replace( "\\n", "\n");
+ txt = txt.replaceAll("\\r", "\r" );
+
+ // unpack our our escaped characters
+ txt = txt.replace("\\|", "|" );
+ // txt = txt.replace("\\\\", "\\" );
+
+ return txt;
+ }
+ /**
+ * Trim leading white space as described Properties file standard.
* @see Properties#load(java.io.Reader)
* @param txt
* @return txt leading whitespace removed
@@ -241,15 +270,62 @@
int split = line.indexOf('=');
fid = line.substring(0, split);
- text = line.substring(split + 1).split("\\|", -1);//use -1 as limit to include empty trailing spaces
- if (type.getAttributeCount() != text.length)
- throw new DataSourceException("format error: expected " + type.getAttributeCount()
- + " attributes, but found " + text.length + ". [" + line + "]");
+ String data = line.substring(split+1);
+
+ text = splitIntoText(data);
} else {
throw new NoSuchElementException();
}
}
+ /**
+ * Split the provided text using | charater as a seperator.
+ * <p>
+ * This method respects the used of \ to "escape" a | character allowing
+ * representations such as the following:<pre>
+ * String example="text|example of escaped \\| character|text";
+ *
+ * // represents: "text|example of escaped \| character|text"
+ * String split=splitIntoText( example );</pre>
+ *
+ * @param data Origional raw text as stored
+ * @return data split using | as seperator
+ * @throws DataSourceException if the information stored is inconsistent with the headered provided
+ */
+ private String[] splitIntoText(String data) throws DataSourceException {
+ // return data.split("|", -1); // use -1 as a limit to include empty trailing spaces
+ // return data.split("[.-^\\\\]\\|",-1); //use -1 as limit to include empty trailing spaces
+ String split[] = new String[type.getAttributeCount()];
+ int i = 0;
+ StringBuilder item = new StringBuilder();
+ for (String str : data.split("\\|",-1)) {
+ if (i == type.getAttributeCount()) {
+ // limit reached
+ throw new DataSourceException("format error: expected " + text.length
+ + " attributes, stopped after finding " + i + ". [" + line
+ + "] split into " + Arrays.asList(text));
+ }
+ if (str.endsWith("\\")) {
+// String shorter = str.substring(0, str.length() - 1);
+// item.append(shorter);
+ item.append(str);
+ item.append("|");
+ } else {
+ item.append(str);
+ split[i] = item.toString();
+
+ i++;
+ item = new StringBuilder();
+ }
+ }
+ if (i < type.getAttributeCount()) {
+ throw new DataSourceException("format error: expected " + type.getAttributeCount()
+ + " attributes, but only found " + i + ". [" + line + "] split into "
+ + Arrays.asList(text));
+ }
+ return split;
+ }
+
/**
* Retrieve the FeatureId identifying the current line.
*
@@ -281,18 +357,18 @@
AttributeDescriptor attType = type.getDescriptor(index);
String stringValue = null;
- boolean isEmpty = "".equals(stringValue);
+ //boolean isEmpty = "".equals(stringValue);
try {
- // read the value
- stringValue = text[index];
- } catch (RuntimeException e1) {
- e1.printStackTrace();
+ // read the value and decode any interesting characters
+ stringValue = decodeString( text[index] );
+ } catch (RuntimeException huh) {
+ huh.printStackTrace();
stringValue = null;
}
// check for special <null> flag
if ("<null>".equals(stringValue)) {
stringValue = null;
- isEmpty = true;
+ // isEmpty = true;
}
if (stringValue == null) {
if (attType.isNillable()) {
Modified: trunk/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyAttributeWriter.java
===================================================================
--- trunk/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyAttributeWriter.java 2012-05-01 18:57:46 UTC (rev 38698)
+++ trunk/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyAttributeWriter.java 2012-05-02 01:23:15 UTC (rev 38699)
@@ -20,6 +20,9 @@
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
+import java.util.regex.MatchResult;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.geotools.data.AttributeWriter;
import org.geotools.data.DataUtilities;
@@ -110,22 +113,42 @@
if (attribute == null) {
writer.write("<null>"); // nothing!
} else if( attribute instanceof String){
- // encode newlines
- String txt = (String) attribute;
- txt = txt.replace("\n", "\\n");
- txt = txt.replace("\r", "\\r");
- writer.write( txt );
+ String txt = encodeString((String) attribute);
+ writer.write( txt );
} else if (attribute instanceof Geometry) {
Geometry geometry = (Geometry) attribute;
- writer.write( geometry.toText() );
+ String txt = geometry.toText();
+
+ txt = encodeString( txt );
+ writer.write( txt );
} else {
String txt = Converters.convert( attribute, String.class );
if( txt == null ){ // could not convert?
txt = attribute.toString();
}
+ txt = encodeString( txt );
writer.write( txt );
}
}
+
+ /**
+ * Used to encode common whitespace characters and | character for safe transport.
+ *
+ * @param txt
+ * @return txt encoded for storage
+ * @see PropertyAttributeReader#decodeString(String)
+ */
+ String encodeString( String txt ){
+ // encode our escaped characters
+ // txt = txt.replace("\\", "\\\\");
+ txt = txt.replace("|","\\|");
+
+ // encode whitespace constants
+ txt = txt.replace("\n", "\\n");
+ txt = txt.replace("\r", "\\r");
+
+ return txt;
+ }
// write end
// close start
Modified: trunk/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyFeatureWriter.java
===================================================================
--- trunk/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyFeatureWriter.java 2012-05-01 18:57:46 UTC (rev 38698)
+++ trunk/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyFeatureWriter.java 2012-05-02 01:23:15 UTC (rev 38699)
@@ -105,6 +105,7 @@
// writeImplementation end
// next start
+ long nextFid = System.currentTimeMillis(); // seed with a big number
public SimpleFeature next() throws IOException {
if (writer == null) {
throw new IOException("Writer has been closed");
@@ -125,7 +126,7 @@
live = SimpleFeatureBuilder.copy(origional);
return live;
} else {
- fid = type.getTypeName() + "." + System.currentTimeMillis();
+ fid = type.getTypeName() + "." + (nextFid++);
Object values[] = DataUtilities.defaultValues(type);
origional = null;
Modified: trunk/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyDataStore2Test.java
===================================================================
--- trunk/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyDataStore2Test.java 2012-05-01 18:57:46 UTC (rev 38698)
+++ trunk/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyDataStore2Test.java 2012-05-02 01:23:15 UTC (rev 38699)
@@ -16,47 +16,72 @@
*/
package org.geotools.data.property;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+
+import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
-import junit.framework.TestCase;
-
-import org.geotools.data.DefaultQuery;
+import org.geotools.data.DataUtilities;
+import org.geotools.data.Query;
+import org.geotools.data.collection.ListFeatureCollection;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
+import org.geotools.data.simple.SimpleFeatureStore;
+import org.geotools.factory.CommonFactoryFinder;
+import org.geotools.factory.Hints;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.referencing.CRS;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.opengis.feature.Feature;
+import org.opengis.feature.FeatureVisitor;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.feature.type.GeometryType;
import org.opengis.filter.Filter;
+import org.opengis.filter.FilterFactory2;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
/**
- * Test non functionality of PropertyDataStore.
+ * Test non functionality of PropertyDataStore (problems and enhancements requested through JIRA).
*
- * @author Jody Garnett, Refractions Research Inc.
+ * @author Jody Garnett (LISAsoft)
*
*
* @source $URL$
*/
-public class PropertyDataStore2Test extends TestCase {
+public class PropertyDataStore2Test {
PropertyDataStore store;
PropertyDataStore sridStore;
- /**
- * Constructor for SimpleDataStoreTest.
- * @param arg0
- */
- public PropertyDataStore2Test(String arg0) {
- super(arg0);
- }
- protected void setUp() throws Exception {
+
+ private PropertyDataStore unusalStore;
+
+ @Before
+ public void setUp() throws Exception {
File dir = new File(".", "propertyTestData" );
dir.mkdir();
@@ -93,24 +118,46 @@
writer2.close();
sridStore = new PropertyDataStore(dir2);
- super.setUp();
+ // Create a similar data store with various unusal problems
+ File dir3 = new File(".", "propertyTestData3");
+ dir3.mkdir();
+ File file3 = new File( dir3 ,"unusual.properties");
+ if( file3.exists()){
+ file3.delete();
+ }
+
+ BufferedWriter writer3 = new BufferedWriter( new FileWriter( file3 ) );
+ writer3.write("_=id:Integer,*geom:Geometry,data:String"); writer3.newLine();
+ writer3.write("fid1=1|LINESTRING(0 0,10 10)|feeling a bit \\|broken up"); writer3.newLine();
+ writer3.write("fid2=2|\\\nLINESTRING(20 20,30 30)|\\\nnew line\\\ndiff friendly");writer3.newLine();
+ writer3.close();
+ unusalStore = new PropertyDataStore( dir3 );
+
+ // listFileContents( file3 );
}
- protected void tearDown() throws Exception {
+
+ @After
+ public void tearDown() throws Exception {
+ store.dispose();
File dir = new File( "propertyTestData" );
- File list[]=dir.listFiles();
- for( int i=0; i<list.length;i++){
- list[i].delete();
+ for( File file : dir.listFiles()){
+ file.delete();
}
dir.delete();
-
+
+ sridStore.dispose();
dir = new File( "propertyTestData2" );
- File list2[] = dir.listFiles();
- for( int i=0; i<list2.length;i++){
- list2[i].delete();
+ for( File file : dir.listFiles()){
+ file.delete();
}
dir.delete();
-
- super.tearDown();
+
+ unusalStore.dispose();
+ dir = new File( "propertyTestData3" );
+ for( File file : dir.listFiles()){
+ file.delete();
+ }
+ dir.delete();
}
/**
@@ -118,6 +165,7 @@
*
* @throws Exception
*/
+ @Test
public void testCRS() throws Exception {
SimpleFeatureSource road = sridStore.getFeatureSource("road2");
SimpleFeatureCollection features = road.getFeatures();
@@ -144,7 +192,37 @@
assertEquals(userData, geomType.getCoordinateReferenceSystem());
}
}
-
+ @Test
+ public void unusual() throws Exception {
+ SimpleFeatureSource road = unusalStore.getFeatureSource( "unusual" );
+ assertEquals( 3, road.getSchema().getAttributeCount() );
+
+ SimpleFeatureCollection features = road.getFeatures();
+ assertFalse( features.isEmpty() );
+
+ FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
+
+ SimpleFeatureCollection select = road.getFeatures( ff.id( ff.featureId("fid1")));
+ SimpleFeatureIterator iterator = select.features();
+ SimpleFeature feature1 = iterator.next();
+ assertNotNull( feature1 );
+ iterator.close();
+
+ select = road.getFeatures( ff.id( ff.featureId("fid2")));
+ iterator = select.features();
+ SimpleFeature feature2 = iterator.next();
+ assertNotNull( feature2 );
+ iterator.close();
+
+ // Encode |
+ assertEquals("feeling a bit |broken up", feature1.getAttribute("data"));
+
+ // Encode newline; but still respect trim of white space
+ assertTrue( feature2.getAttribute("geom") instanceof LineString );
+ assertEquals("\nnew line\ndiff friendly", feature2.getAttribute("data"));
+ }
+ @Test
+
public void testSimple() throws Exception {
SimpleFeatureSource road = store.getFeatureSource( "road" );
SimpleFeatureCollection features = road.getFeatures();
@@ -152,17 +230,19 @@
//assertEquals( 1, features.getFeatureType().getAttributeCount() );
assertEquals( 4, features.size() );
}
+ @Test
+
public void testQuery() throws Exception {
SimpleFeatureSource road = store.getFeatureSource( "road" );
- DefaultQuery query = new DefaultQuery( "road", Filter.INCLUDE,
+ Query query = new Query( "road", Filter.INCLUDE,
new String[]{ "name" } );
SimpleFeatureCollection features = road.getFeatures( query );
assertEquals( 4, features.size() );
//assertEquals( 1, features.getFeatureType().getAttributeCount() );
}
-
+ @Test
public void testQueryReproject() throws Exception {
CoordinateReferenceSystem world = CRS.decode("EPSG:4326"); // world lon/lat
CoordinateReferenceSystem local = CRS.decode("EPSG:3005"); // british columbia
@@ -171,7 +251,7 @@
SimpleFeatureSource road = store.getFeatureSource( "road" );
SimpleFeatureType origionalType = road.getSchema();
- DefaultQuery query = new DefaultQuery( "road", Filter.INCLUDE,
+ Query query = new Query( "road", Filter.INCLUDE,
new String[]{ "geom", "name" } );
query.setCoordinateSystem( local ); // FROM
@@ -187,5 +267,96 @@
assertEquals( world, resultType.getCoordinateReferenceSystem() );
GeometryDescriptor geometryDescriptor = resultType.getGeometryDescriptor();
+ assertTrue( Geometry.class.isAssignableFrom( geometryDescriptor.getType().getBinding() ) );
}
+ @Test
+ public void testUnusalRoundTrip() throws Throwable {
+
+ File target = new File( "propertyTestData3/trip.properties" );
+ if( target.exists() ){
+ boolean deleted = target.delete();
+ assertTrue( "unable to delete "+target.getAbsolutePath(), deleted );
+ }
+ assertFalse( "trip.properties should not exist yet", target.exists() );
+
+
+ SimpleFeatureType schema = DataUtilities.createType("trip", "point:Point::srid=4326,text:String, number:Integer");
+ SimpleFeatureBuilder builder = new SimpleFeatureBuilder( schema );
+ GeometryFactory gf = JTSFactoryFinder.getGeometryFactory();
+
+ List<SimpleFeature> list = new ArrayList<SimpleFeature>();
+ SimpleFeature feature;
+
+ feature = builder.buildFeature("trip1", new Object[]{gf.createPoint( new Coordinate(0,0)), "hello world", 1 });
+ feature.getUserData().put( Hints.USE_PROVIDED_FID, true );
+ list.add( feature);
+
+ feature = builder.buildFeature("trip2", new Object[]{gf.createPoint( new Coordinate(0,0)), "test if | chracter handling", 2 });
+ feature.getUserData().put( Hints.USE_PROVIDED_FID, true );
+ list.add( feature );
+
+ feature= builder.buildFeature("trip3", new Object[]{gf.createPoint( new Coordinate(0,0)), "test of\n multi-line handling", 3 });
+ feature.getUserData().put( Hints.USE_PROVIDED_FID, true );
+ list.add( feature );
+
+ feature = builder.buildFeature("trip4", new Object[]{gf.createPoint( new Coordinate(0,0)), " test of\n whitespace handling", 4 });
+ feature.getUserData().put( Hints.USE_PROVIDED_FID, true );
+ list.add( feature );
+
+ feature = builder.buildFeature("trip5", new Object[]{gf.createPoint( new Coordinate(0,0)), "test encoding does not get confused over \\n newline and \\twhite space and \\| other markers", 5 });
+ feature.getUserData().put( Hints.USE_PROVIDED_FID, true );
+ list.add( feature );
+
+ feature = builder.buildFeature("trip6", new Object[]{gf.createPoint( new Coordinate(0,0)), "How well can we encode 1\\2?", 5 });
+ feature.getUserData().put( Hints.USE_PROVIDED_FID, true );
+ list.add( feature );
+
+ ListFeatureCollection features = new ListFeatureCollection(schema, list );
+
+ unusalStore.createSchema( schema );
+ SimpleFeatureStore trip = (SimpleFeatureStore) unusalStore.getFeatureSource("trip");
+
+ trip.addFeatures( features );
+ assertTrue( "trip.properties created", target.exists() );
+
+ // listFileContents(target);
+
+ assertEquals("stored", list.size(), trip.getCount(Query.ALL));
+
+ final Map<String,SimpleFeature> cache = new HashMap<String,SimpleFeature>();
+ SimpleFeatureCollection readFeatures = trip.getFeatures();
+
+ FeatureVisitor cacheResults = new FeatureVisitor() {
+ @Override
+ public void visit(Feature f) {
+ SimpleFeature feature = (SimpleFeature) f;
+ cache.put( feature.getID(), feature );
+ }
+ };
+ readFeatures.accepts( cacheResults, null );
+ assertEquals( "restored", list.size(), cache.size() );
+ assertEquals( "hello world", cache.get("trip1").getAttribute("text"));
+ assertEquals( "test if | chracter handling", cache.get("trip2").getAttribute("text"));
+ assertEquals( "test of\n multi-line handling", cache.get("trip3").getAttribute("text"));
+ assertEquals( " test of\n whitespace handling", cache.get("trip4").getAttribute("text"));
+
+ // need some regex magic to make this work
+ //assertEquals( "test encoding does not get confused over \\n newline and \\twhite space and \\| other markers", cache.get("trip5").getAttribute("text"));
+ assertEquals( "How well can we encode 1\\2?", cache.get("trip6").getAttribute("text"));
+ }
+
+ private void listFileContents(File target) throws FileNotFoundException, IOException {
+ System.out.println("Contents of "+target );
+ if( target.exists() ){
+ BufferedReader reader = new BufferedReader( new FileReader( target ) );
+ String line;
+ while( (line = reader.readLine()) != null ){
+ System.out.println( line );
+ }
+ reader.close();
+ }
+ else {
+ System.out.println(" ... does not exist");
+ }
+ }
}
Modified: trunk/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyDataStoreTest.java
===================================================================
--- trunk/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyDataStoreTest.java 2012-05-01 18:57:46 UTC (rev 38698)
+++ trunk/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyDataStoreTest.java 2012-05-02 01:23:15 UTC (rev 38699)
@@ -25,12 +25,10 @@
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
-import java.util.Set;
import junit.framework.TestCase;
import org.geotools.data.DataUtilities;
-import org.geotools.data.DefaultQuery;
import org.geotools.data.DefaultTransaction;
import org.geotools.data.FeatureReader;
import org.geotools.data.FeatureWriter;
@@ -43,7 +41,6 @@
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.factory.Hints;
import org.geotools.feature.simple.SimpleFeatureBuilder;
-import org.geotools.filter.identity.FeatureIdImpl;
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureVisitor;
import org.opengis.feature.IllegalAttributeException;
@@ -55,497 +52,539 @@
import org.opengis.filter.identity.FeatureId;
/**
- * Test functioning of PropertyDataStore.
+ * Test functioning of PropertyDataStore (used as conformance testing and examples for the AbstractDataStore tutorial).
*
- * @author Jody Garnett, Refractions Research Inc.
- *
- *
+ * @author Jody Garnett (LISAsoft)
+ *
* @source $URL$
*/
public class PropertyDataStoreTest extends TestCase {
PropertyDataStore store;
-
+
static FilterFactory2 ff = (FilterFactory2) CommonFactoryFinder.getFilterFactory(null);
/**
* Constructor for SimpleDataStoreTest.
+ *
* @param arg0
*/
public PropertyDataStoreTest(String arg0) {
super(arg0);
}
+
protected void setUp() throws Exception {
- File dir = new File(".", "propertyTestData" );
+ File dir = new File(".", "propertyTestData");
dir.mkdir();
-
- File file = new File( dir ,"road.properties");
- if( file.exists()){
+
+ File file = new File(dir, "road.properties");
+ if (file.exists()) {
file.delete();
- }
- BufferedWriter writer = new BufferedWriter( new FileWriter( file ) );
- writer.write("_=id:Integer,name:String"); writer.newLine();
- writer.write("fid1=1|jody"); writer.newLine();
- writer.write("fid2=2|brent"); writer.newLine();
- writer.write("fid3=3|dave"); writer.newLine();
- writer.write("fid4=4|justin"); writer.newLine();
+ }
+ BufferedWriter writer = new BufferedWriter(new FileWriter(file));
+ writer.write("_=id:Integer,name:String");
+ writer.newLine();
+ writer.write("fid1=1|jody");
+ writer.newLine();
+ writer.write("fid2=2|brent");
+ writer.newLine();
+ writer.write("fid3=3|dave");
+ writer.newLine();
+ writer.write("fid4=4|justin");
+ writer.newLine();
writer.write("fid5=5|");
writer.close();
-
- file = new File( dir ,"dots.in.name.properties");
- if( file.exists()){
+
+ file = new File(dir, "dots.in.name.properties");
+ if (file.exists()) {
file.delete();
- }
- writer = new BufferedWriter( new FileWriter( file ) );
- writer.write("_=id:Integer,name:String"); writer.newLine();
- writer.write("fid1=1|jody"); writer.newLine();
- writer.write("fid2=2|brent"); writer.newLine();
- writer.write("fid3=3|dave"); writer.newLine();
+ }
+ writer = new BufferedWriter(new FileWriter(file));
+ writer.write("_=id:Integer,name:String");
+ writer.newLine();
+ writer.write("fid1=1|jody");
+ writer.newLine();
+ writer.write("fid2=2|brent");
+ writer.newLine();
+ writer.write("fid3=3|dave");
+ writer.newLine();
writer.write("fid4=4|justin");
writer.close();
- file = new File( dir ,"multiline.properties");
- if( file.exists()){
+ file = new File(dir, "multiline.properties");
+ if (file.exists()) {
file.delete();
- }
- writer = new BufferedWriter( new FileWriter( file ) );
- writer.write("_=id:Integer,name:String"); writer.newLine();
- writer.write("fid1=1|jody \\"); writer.newLine();
- writer.write(" garnett"); writer.newLine();
- writer.write("fid2=2|brent"); writer.newLine();
- writer.write("fid3=3|dave"); writer.newLine();
+ }
+ writer = new BufferedWriter(new FileWriter(file));
+ writer.write("_=id:Integer,name:String");
+ writer.newLine();
+ writer.write("fid1=1|jody \\");
+ writer.newLine();
+ writer.write(" garnett");
+ writer.newLine();
+ writer.write("fid2=2|brent");
+ writer.newLine();
+ writer.write("fid3=3|dave");
+ writer.newLine();
writer.write("fid4=4|justin\\\n");
writer.close();
- file = new File( dir ,"table.properties");
- if( file.exists()){
+ file = new File(dir, "table.properties");
+ if (file.exists()) {
file.delete();
- }
- writer = new BufferedWriter( new FileWriter( file ) );
- writer.write("_=description:String,name:String"); writer.newLine();
- writer.write("GenericEntity.f004=description-f004|name-f004"); writer.newLine();
- writer.write("GenericEntity.f003=description-f003|<null>"); writer.newLine();
- writer.write("GenericEntity.f007=description-f007|"); writer.newLine();
- writer.write(" GenericEntity.f009=description-f009| "); writer.newLine();
+ }
+ writer = new BufferedWriter(new FileWriter(file));
+ writer.write("_=description:String,name:String");
+ writer.newLine();
+ writer.write("GenericEntity.f004=description-f004|name-f004");
+ writer.newLine();
+ writer.write("GenericEntity.f003=description-f003|<null>");
+ writer.newLine();
+ writer.write("GenericEntity.f007=description-f007|");
+ writer.newLine();
+ writer.write(" GenericEntity.f009=description-f009| ");
+ writer.newLine();
writer.close();
-
- store = new PropertyDataStore( dir );
+
+ store = new PropertyDataStore(dir);
super.setUp();
}
+
protected void tearDown() throws Exception {
- File dir = new File( "propertyTestData" );
- File list[]=dir.listFiles();
- for( int i=0; i<list.length;i++){
+ File dir = new File("propertyTestData");
+ File list[] = dir.listFiles();
+ for (int i = 0; i < list.length; i++) {
list[i].delete();
}
dir.delete();
- super.tearDown();
+ super.tearDown();
}
public void testGetNames() {
String names[] = store.getTypeNames();
Arrays.sort(names);
- assertEquals( 4, names.length );
- assertEquals( "dots.in.name", names[0] );
- assertEquals( "multiline", names[1] );
- assertEquals( "road", names[2] );
- assertEquals( "table", names[3] );
+ assertEquals(4, names.length);
+ assertEquals("dots.in.name", names[0]);
+ assertEquals("multiline", names[1]);
+ assertEquals("road", names[2]);
+ assertEquals("table", names[3]);
}
public void testGetSchema() throws IOException {
- SimpleFeatureType type = store.getSchema( "road" );
- assertNotNull( type );
- assertEquals( "road", type.getTypeName() );
- assertEquals( "propertyTestData", type.getName().getNamespaceURI().toString() );
- assertEquals( 2, type.getAttributeCount() );
-
- AttributeDescriptor id = type.getDescriptor(0);
+ SimpleFeatureType type = store.getSchema("road");
+ assertNotNull(type);
+ assertEquals("road", type.getTypeName());
+ assertEquals("propertyTestData", type.getName().getNamespaceURI().toString());
+ assertEquals(2, type.getAttributeCount());
+
+ AttributeDescriptor id = type.getDescriptor(0);
AttributeDescriptor name = type.getDescriptor(1);
-
- assertEquals( "id", id.getLocalName() );
- assertEquals( "class java.lang.Integer", id.getType().getBinding().toString() );
-
- assertEquals( "name", name.getLocalName() );
- assertEquals( "class java.lang.String", name.getType().getBinding().toString() );
+
+ assertEquals("id", id.getLocalName());
+ assertEquals("class java.lang.Integer", id.getType().getBinding().toString());
+
+ assertEquals("name", name.getLocalName());
+ assertEquals("class java.lang.String", name.getType().getBinding().toString());
}
+
public void testGetFeaturesFeatureTypeFilterTransaction1() throws Exception {
- SimpleFeatureType type = store.getSchema( "road" );
- Query roadQuery = new DefaultQuery("road");
- FeatureReader<SimpleFeatureType, SimpleFeature> reader = store.getFeatureReader( roadQuery, Transaction.AUTO_COMMIT );
+ Query roadQuery = new Query("road");
+ FeatureReader<SimpleFeatureType, SimpleFeature> reader = store.getFeatureReader(roadQuery,
+ Transaction.AUTO_COMMIT);
int count = 0;
try {
- while( reader.hasNext() ){
+ while (reader.hasNext()) {
reader.next();
count++;
}
- }
- finally {
+ } finally {
reader.close();
}
- assertEquals( 5, count );
-
+ assertEquals(5, count);
+
Filter selectFid1;
-
- selectFid1 = ff.id( Collections.singleton( ff.featureId("fid1") ) );
- reader = store.getFeatureReader( new DefaultQuery("road", selectFid1 ), Transaction.AUTO_COMMIT );
- assertEquals( 1, count( reader ) );
-
+
+ selectFid1 = ff.id(Collections.singleton(ff.featureId("fid1")));
+ reader = store.getFeatureReader(new Query("road", selectFid1), Transaction.AUTO_COMMIT);
+ assertEquals(1, count(reader));
+
Transaction transaction = new DefaultTransaction();
- reader = store.getFeatureReader( roadQuery, transaction );
- assertEquals( 5, count( reader ));
-
- reader = store.getFeatureReader( roadQuery, transaction );
- List list = new ArrayList();
+ reader = store.getFeatureReader(roadQuery, transaction);
+ assertEquals(5, count(reader));
+
+ reader = store.getFeatureReader(roadQuery, transaction);
+ List<String> list = new ArrayList<String>();
try {
- while( reader.hasNext() ){
- list.add( reader.next().getID() );
+ while (reader.hasNext()) {
+ list.add(reader.next().getID());
}
- }
- finally {
+ } finally {
reader.close();
}
- assertEquals( "[fid1, fid2, fid3, fid4, fid5]", list.toString() );
+ assertEquals("[fid1, fid2, fid3, fid4, fid5]", list.toString());
}
+
/*
- * Test for FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(String)
+ * Test for FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(String)
*/
- public void testGetFeatureReaderString() throws NoSuchElementException, IOException, IllegalAttributeException {
- FeatureReader<SimpleFeatureType, SimpleFeature> reader = store.getFeatureReader("road");
+ public void testGetFeatureReaderString() throws NoSuchElementException, IOException,
+ IllegalAttributeException {
+ FeatureReader<SimpleFeatureType, SimpleFeature> reader = store.getFeatureReader("road");
int count = 0;
try {
- while( reader.hasNext() ){
- reader.next();
+ while (reader.hasNext()) {
+ reader.next();
count++;
}
- }
- finally {
+ } finally {
reader.close();
}
- assertEquals( 5, count );
+ assertEquals(5, count);
}
- private int count( FeatureReader<SimpleFeatureType, SimpleFeature> reader ) throws Exception {
+
+ private int count(FeatureReader<SimpleFeatureType, SimpleFeature> reader) throws Exception {
int count = 0;
try {
- while( reader.hasNext() ){
+ while (reader.hasNext()) {
reader.next();
count++;
}
- }
- finally {
+ } finally {
reader.close();
}
- return count;
- }
- private int count( String typeName ) throws Exception {
- return count( store.getFeatureReader( typeName ) );
+ return count;
}
-
+
+ private int count(String typeName) throws Exception {
+ return count(store.getFeatureReader(typeName));
+ }
+
public void testWriterSkipThrough() throws Exception {
- PropertyFeatureWriter writer = (PropertyFeatureWriter)
- store.createFeatureWriter("road",Transaction.AUTO_COMMIT);
-
+ PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road",
+ Transaction.AUTO_COMMIT);
+
File in = writer.read;
File out = writer.write;
-
+
int count = 0;
- while( writer.hasNext() ){
+ while (writer.hasNext()) {
writer.next();
count++;
}
- assertEquals( 5, count );
- assertTrue( in.exists() );
- assertTrue( out.exists() );
+ assertEquals(5, count);
+ assertTrue(in.exists());
+ assertTrue(out.exists());
writer.close();
- assertTrue( in.exists() );
-
- assertEquals( 5, count( "road" ) );
+ assertTrue(in.exists());
+
+ assertEquals(5, count("road"));
}
- public void testWriterChangeName() throws Exception{
- PropertyFeatureWriter writer = (PropertyFeatureWriter)
- store.createFeatureWriter("road",Transaction.AUTO_COMMIT);
-
+
+ public void testWriterChangeName() throws Exception {
+ PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road",
+ Transaction.AUTO_COMMIT);
+
int count = 0;
- while( writer.hasNext() ){
+ while (writer.hasNext()) {
SimpleFeature f = writer.next();
- f.setAttribute(1,"name "+(count+1));
+ f.setAttribute(1, "name " + (count + 1));
writer.write();
count++;
- }
- writer.close();
- assertEquals( 5, count );
- assertEquals( 5, count( "road" ));
+ }
+ writer.close();
+ assertEquals(5, count);
+ assertEquals(5, count("road"));
}
- public void testWriterChangeFirstName() throws Exception{
- PropertyFeatureWriter writer = (PropertyFeatureWriter)
- store.createFeatureWriter("road",Transaction.AUTO_COMMIT);
+
+ public void testWriterChangeFirstName() throws Exception {
+ PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road",
+ Transaction.AUTO_COMMIT);
SimpleFeature f;
f = writer.next();
- f.setAttribute(1,"changed");
+ f.setAttribute(1, "changed");
writer.write();
- writer.close();
- assertEquals( 5, count( "road" ));
+ writer.close();
+ assertEquals(5, count("road"));
}
- public void testWriterChangeLastName() throws Exception{
- PropertyFeatureWriter writer = (PropertyFeatureWriter)
- store.createFeatureWriter("road",Transaction.AUTO_COMMIT);
+
+ public void testWriterChangeLastName() throws Exception {
+ PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road",
+ Transaction.AUTO_COMMIT);
SimpleFeature f;
writer.next();
writer.next();
- writer.next();
+ writer.next();
f = writer.next();
- f.setAttribute(1,"changed");
+ f.setAttribute(1, "changed");
writer.write();
- writer.close();
- assertEquals( 5, count( "road" ));
- }
- public void testWriterChangeAppend() throws Exception{
- PropertyFeatureWriter writer = (PropertyFeatureWriter)
- store.createFeatureWriter("road",Transaction.AUTO_COMMIT);
+ writer.close();
+ assertEquals(5, count("road"));
+ }
+
+ public void testWriterChangeAppend() throws Exception {
+ PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road",
+ Transaction.AUTO_COMMIT);
SimpleFeature f;
writer.next();
writer.next();
writer.next();
writer.next();
writer.next();
- assertFalse( writer.hasNext() );
+ assertFalse(writer.hasNext());
f = writer.next();
- assertNotNull( f );
- f.setAttribute(0,new Integer(-1));
- f.setAttribute(1,"new");
+ assertNotNull(f);
+ f.setAttribute(0, new Integer(-1));
+ f.setAttribute(1, "new");
writer.write();
writer.close();
- assertEquals( 6, count( "road" ));
+ assertEquals(6, count("road"));
}
- public void testWriterAppendLastNull() throws Exception{
- FeatureWriter<SimpleFeatureType, SimpleFeature> writer = (FeatureWriter)
- store.getFeatureWriterAppend("road", Transaction.AUTO_COMMIT);
+
+ public void testWriterAppendLastNull() throws Exception {
+ FeatureWriter<SimpleFeatureType, SimpleFeature> writer = store
+ .getFeatureWriterAppend("road", Transaction.AUTO_COMMIT);
SimpleFeature f;
- assertFalse( writer.hasNext() );
+ assertFalse(writer.hasNext());
f = writer.next();
- assertNotNull( f );
- f.setAttribute(0,new Integer(-1));
- f.setAttribute(1,null); // this made the datastore break
+ assertNotNull(f);
+ f.setAttribute(0, new Integer(-1));
+ f.setAttribute(1, null); // this made the datastore break
writer.write();
writer.close();
- assertEquals( 6, count( "road" ));
+ assertEquals(6, count("road"));
}
- public void testWriterChangeRemoveFirst() throws Exception{
- PropertyFeatureWriter writer = (PropertyFeatureWriter)
- store.createFeatureWriter("road",Transaction.AUTO_COMMIT);
-
+
+ public void testWriterChangeRemoveFirst() throws Exception {
+ PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road",
+ Transaction.AUTO_COMMIT);
+
writer.next();
writer.remove();
writer.close();
- assertEquals( 4, count( "road" ));
+ assertEquals(4, count("road"));
}
- public void testWriterChangeRemoveLast() throws Exception{
- PropertyFeatureWriter writer = (PropertyFeatureWriter)
- store.createFeatureWriter("road",Transaction.AUTO_COMMIT);
-
+
+ public void testWriterChangeRemoveLast() throws Exception {
+ PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road",
+ Transaction.AUTO_COMMIT);
+
writer.next();
writer.next();
writer.next();
writer.remove();
writer.close();
- assertEquals( 4, count( "road" ));
+ assertEquals(4, count("road"));
}
- public void testWriterChangeRemoveAppend() throws Exception{
- PropertyFeatureWriter writer = (PropertyFeatureWriter)
- store.createFeatureWriter("road",Transaction.AUTO_COMMIT);
+
+ public void testWriterChangeRemoveAppend() throws Exception {
+ PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road",
+ Transaction.AUTO_COMMIT);
SimpleFeature f;
writer.next();
writer.next();
writer.next();
- writer.next();
- writer.next();
-
- assertFalse( writer.hasNext() );
+ writer.next();
+ writer.next();
+
+ assertFalse(writer.hasNext());
f = writer.next();
- assertNotNull( f );
- f.setAttribute(0,new Integer(-1));
- f.setAttribute(1,"new");
+ assertNotNull(f);
+ f.setAttribute(0, new Integer(-1));
+ f.setAttribute(1, "new");
writer.remove();
writer.close();
- assertEquals( 5, count( "road" ));
+ assertEquals(5, count("road"));
}
- public void testWriterChangeIgnoreAppend() throws Exception{
- PropertyFeatureWriter writer = (PropertyFeatureWriter)
- store.createFeatureWriter("road",Transaction.AUTO_COMMIT);
+
+ public void testWriterChangeIgnoreAppend() throws Exception {
+ PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road",
+ Transaction.AUTO_COMMIT);
SimpleFeature f;
writer.next();
writer.next();
writer.next();
writer.next();
writer.next();
- assertFalse( writer.hasNext() );
+ assertFalse(writer.hasNext());
f = writer.next();
- assertNotNull( f );
- f.setAttribute(0,new Integer(-1));
- f.setAttribute(1,"new");
+ assertNotNull(f);
+ f.setAttribute(0, new Integer(-1));
+ f.setAttribute(1, "new");
writer.close();
- assertEquals( 5, count( "road" ));
+ assertEquals(5, count("road"));
}
-
+
public void testGetFeatureSource() throws Exception {
- SimpleFeatureSource road = store.getFeatureSource( "road" );
+ SimpleFeatureSource road = store.getFeatureSource("road");
SimpleFeatureCollection features = road.getFeatures();
SimpleFeatureIterator reader = features.features();
- List list = new ArrayList();
+ List<String> list = new ArrayList<String>();
try {
- while( reader.hasNext() ){
- list.add( reader.next().getID() );
+ while (reader.hasNext()) {
+ list.add(reader.next().getID());
}
} finally {
reader.close();
}
- assertEquals( "[fid1, fid2, fid3, fid4, fid5]", list.toString() );
- assertEquals( 5, road.getCount(Query.ALL) );
- assertTrue( road.getBounds(Query.ALL).isNull() );
- assertEquals( 5, features.size() );
- assertTrue( features.getBounds().isNull() );
- assertEquals( 5, features.size() );
-
+ assertEquals("[fid1, fid2, fid3, fid4, fid5]", list.toString());
+ assertEquals(5, road.getCount(Query.ALL));
+ assertTrue(road.getBounds(Query.ALL).isNull());
+ assertEquals(5, features.size());
+ assertTrue(features.getBounds().isNull());
+ assertEquals(5, features.size());
+
}
/**
- * In response to <a
- * href="https://jira.codehaus.org/browse/GEOT-1409">GEOT-1409 Property
- * datastore ruins the property file if a string attribute has newlines</a>.
+ * In response to <a href="https://jira.codehaus.org/browse/GEOT-1409">GEOT-1409 Property datastore ruins the property file if a string attribute
+ * has newlines</a>.
*
* @throws Exception
*/
public void testMultiLine() throws Exception {
- SimpleFeatureSource road = store.getFeatureSource( "multiline" );
+ SimpleFeatureSource road = store.getFeatureSource("multiline");
FeatureId fid1 = ff.featureId("fid1");
- Filter select = ff.id( Collections.singleton(fid1));
- SimpleFeatureCollection featureCollection = road.getFeatures( select );
+ Filter select = ff.id(Collections.singleton(fid1));
+ SimpleFeatureCollection featureCollection = road.getFeatures(select);
featureCollection.accepts(new FeatureVisitor() {
public void visit(Feature f) {
SimpleFeature feature = (SimpleFeature) f;
String name = (String) feature.getAttribute("name");
- assertEquals( "jody \ngarnett", name );
+ assertEquals("jody \ngarnett", name);
}
- },null);
+ }, null);
}
/**
- * In response to <a
- * href="http://jira.codehaus.org/browse/GEOT-3540">GEOT-3540
- * PropertyDataStore doesn't support empty trailing spaces</a>.
+ * In response to <a href="http://jira.codehaus.org/browse/GEOT-3540">GEOT-3540 PropertyDataStore doesn't support empty trailing spaces</a>.
* <p>
* Table with no geoemtry, containing null and empty strings at end of line
* </p>
*
* @throws Exception
*/
- public void testTable() throws Exception{
- SimpleFeatureSource table = store.getFeatureSource( "table" );
- //GenericEntity.f004=description-f004|name-f004
+ public void testTable() throws Exception {
+ SimpleFeatureSource table = store.getFeatureSource("table");
+ // GenericEntity.f004=description-f004|name-f004
FeatureId fid1 = ff.featureId("GenericEntity.f004");
- Filter select = ff.id( Collections.singleton(fid1));
- SimpleFeatureCollection featureCollection = table.getFeatures( select );
+ Filter select = ff.id(Collections.singleton(fid1));
+ SimpleFeatureCollection featureCollection = table.getFeatures(select);
featureCollection.accepts(new FeatureVisitor() {
public void visit(Feature f) {
SimpleFeature feature = (SimpleFeature) f;
String name = (String) feature.getAttribute("name");
- assertEquals( "name-f004", name );
+ assertEquals("name-f004", name);
}
- },null);
- //GenericEntity.f003=description-f003|<null>
+ }, null);
+ // GenericEntity.f003=description-f003|<null>
fid1 = ff.featureId("GenericEntity.f003");
- select = ff.id( Collections.singleton(fid1));
- featureCollection = table.getFeatures( select );
+ select = ff.id(Collections.singleton(fid1));
+ featureCollection = table.getFeatures(select);
featureCollection.accepts(new FeatureVisitor() {
public void visit(Feature f) {
SimpleFeature feature = (SimpleFeature) f;
String name = (String) feature.getAttribute("name");
- System.out.println( name );
- assertNull( "represent null", name );
+ System.out.println(name);
+ assertNull("represent null", name);
}
- },null);
- //GenericEntity.f007=description-f007|
+ }, null);
+ // GenericEntity.f007=description-f007|
fid1 = ff.featureId("GenericEntity.f007");
- select = ff.id( Collections.singleton(fid1));
- featureCollection = table.getFeatures( select );
+ select = ff.id(Collections.singleton(fid1));
+ featureCollection = table.getFeatures(select);
featureCollection.accepts(new FeatureVisitor() {
public void visit(Feature f) {
SimpleFeature feature = (SimpleFeature) f;
String name = (String) feature.getAttribute("name");
- assertEquals( "represent empty string", "", name );
+ assertEquals("represent empty string", "", name);
}
- },null);
- //" GenericEntity.f009=description-f009| "
+ }, null);
+ // " GenericEntity.f009=description-f009| "
fid1 = ff.featureId("GenericEntity.f009");
- select = ff.id( Collections.singleton(fid1));
- featureCollection = table.getFeatures( select );
+ select = ff.id(Collections.singleton(fid1));
+ featureCollection = table.getFeatures(select);
featureCollection.accepts(new FeatureVisitor() {
public void visit(Feature f) {
SimpleFeature feature = (SimpleFeature) f;
String name = (String) feature.getAttribute("name");
- assertEquals( "represent empty string", " ", name );
+ assertEquals("represent empty string", " ", name);
}
- },null);
+ }, null);
}
+
public void testTransactionIndependence() throws Exception {
- SimpleFeatureType ROAD = store.getSchema( "road" );
- SimpleFeature chrisFeature =
- SimpleFeatureBuilder.build(ROAD, new Object[]{ new Integer(5), "chris"}, "fid5" );
-
+ SimpleFeatureType ROAD = store.getSchema("road");
+ SimpleFeature chrisFeature = SimpleFeatureBuilder.build(ROAD, new Object[] {
+ new Integer(5), "chris" }, "fid5");
+
SimpleFeatureStore roadAuto = (SimpleFeatureStore) store.getFeatureSource("road");
-
+
SimpleFeatureStore roadFromClient1 = (SimpleFeatureStore) store.getFeatureSource("road");
Transaction transaction1 = new DefaultTransaction("Transaction Used by Client 1");
- roadFromClient1.setTransaction( transaction1 );
-
+ roadFromClient1.setTransaction(transaction1);
+
SimpleFeatureStore roadFromClient2 = (SimpleFeatureStore) store.getFeatureSource("road");
Transaction transaction2 = new DefaultTransaction("Transaction Used by Client 2");
- roadFromClient2.setTransaction( transaction2 );
+ roadFromClient2.setTransaction(transaction2);
FilterFactory2 ff = (FilterFactory2) CommonFactoryFinder.getFilterFactory(null);
- Filter selectFid1 = ff.id( Collections.singleton( ff.featureId("fid1") ));
-
+ Filter selectFid1 = ff.id(Collections.singleton(ff.featureId("fid1")));
+
// Before we edit everything should be the same
- assertEquals( "auto before", 5, roadAuto.getFeatures().size() );
- assertEquals( "client 1 before", 5, roadFromClient1.getFeatures().size() );
- assertEquals( "client 2 before", 5, roadFromClient2.getFeatures().size() );
+ assertEquals("auto before", 5, roadAuto.getFeatures().size());
+ assertEquals("client 1 before", 5, roadFromClient1.getFeatures().size());
+ assertEquals("client 2 before", 5, roadFromClient2.getFeatures().size());
// Remove Feature with Fid1
- roadFromClient1.removeFeatures( selectFid1 ); // road1 removes fid1 on t1
-
- assertEquals( "auto after client 1 removes fid1", 5, roadAuto.getFeatures().size() );
- assertEquals( "client 1 after client 1 removes fid1", 4, roadFromClient1.getFeatures().size() );
- assertEquals( "client 2 after client 1 removes fid1", 5, roadFromClient2.getFeatures().size() );
-
- roadFromClient2.addFeatures( DataUtilities.collection( chrisFeature )); // road2 adds fid5 on t2
- assertEquals( "auto after client 1 removes fid1 and client 2 adds fid5", 5, roadAuto.getFeatures().size() );
- assertEquals( "client 1 after client 1 removes fid1 and client 2 adds fid5", 4, roadFromClient1.getFeatures().size() );
- assertEquals( "cleint 2 after client 1 removes fid1 and client 2 adds fid5", 6, roadFromClient2.getFeatures().size() );
+ roadFromClient1.removeFeatures(selectFid1); // road1 removes fid1 on t1
+ assertEquals("auto after client 1 removes fid1", 5, roadAuto.getFeatures().size());
+ assertEquals("client 1 after client 1 removes fid1", 4, roadFromClient1.getFeatures()
+ .size());
+ assertEquals("client 2 after client 1 removes fid1", 5, roadFromClient2.getFeatures()
+ .size());
+
+ roadFromClient2.addFeatures(DataUtilities.collection(chrisFeature)); // road2 adds fid5 on t2
+ assertEquals("auto after client 1 removes fid1 and client 2 adds fid5", 5, roadAuto
+ .getFeatures().size());
+ assertEquals("client 1 after client 1 removes fid1 and client 2 adds fid5", 4,
+ roadFromClient1.getFeatures().size());
+ assertEquals("cleint 2 after client 1 removes fid1 and client 2 adds fid5", 6,
+ roadFromClient2.getFeatures().size());
+
transaction1.commit();
- assertEquals( "auto after client 1 commits removal of fid1 (client 2 has added fid5)", 4, roadAuto.getFeatures().size() );
- assertEquals( "client 1 after commiting removal of fid1 (client 2 has added fid5)", 4, roadFromClient1.getFeatures().size() );
- assertEquals( "client 2 after client 1 commits removal of fid1 (client 2 has added fid5)", 5, roadFromClient2.getFeatures().size() );
-
+ assertEquals("auto after client 1 commits removal of fid1 (client 2 has added fid5)", 4,
+ roadAuto.getFeatures().size());
+ assertEquals("client 1 after commiting removal of fid1 (client 2 has added fid5)", 4,
+ roadFromClient1.getFeatures().size());
+ assertEquals("client 2 after client 1 commits removal of fid1 (client 2 has added fid5)",
+ 5, roadFromClient2.getFeatures().size());
+
transaction2.commit();
- assertEquals( "auto after client 2 commits addition of fid5 (fid1 previously removed)", 5, roadAuto.getFeatures().size() );
- assertEquals( "client 1 after client 2 commits addition of fid5 (fid1 previously removed)", 5, roadFromClient1.getFeatures().size() );
- assertEquals( "client 2 after commiting addition of fid5 (fid1 previously removed)", 5, roadFromClient2.getFeatures().size() );
+ assertEquals("auto after client 2 commits addition of fid5 (fid1 previously removed)", 5,
+ roadAuto.getFeatures().size());
+ assertEquals("client 1 after client 2 commits addition of fid5 (fid1 previously removed)",
+ 5, roadFromClient1.getFeatures().size());
+ assertEquals("client 2 after commiting addition of fid5 (fid1 previously removed)", 5,
+ roadFromClient2.getFeatures().size());
}
-
+
public void testUseExistingFid() throws Exception {
- SimpleFeatureType ROAD = store.getSchema( "road" );
- SimpleFeature chrisFeature = SimpleFeatureBuilder.build(ROAD, new Object[]{ new Integer(5), "chris"}, "fid5" );
+ SimpleFeatureType ROAD = store.getSchema("road");
+ SimpleFeature chrisFeature = SimpleFeatureBuilder.build(ROAD, new Object[] {
+ new Integer(5), "chris" }, "fid5");
chrisFeature.getUserData().put(Hints.USE_PROVIDED_FID, Boolean.TRUE);
-
+
SimpleFeatureStore roadAuto = (SimpleFeatureStore) store.getFeatureSource("road");
List<FeatureId> fids = roadAuto.addFeatures(DataUtilities.collection(chrisFeature));
-
+
// checke the id was preserved
assertEquals(1, fids.size());
FeatureId fid = SimpleFeatureBuilder.createDefaultFeatureIdentifier("fid5");
assertTrue(fids.contains(fid));
-
+
// manually check the feature with the proper id is actually there
- SimpleFeatureIterator it = roadAuto.getFeatures(ff.id(Collections.singleton(fid))).features();
+ SimpleFeatureIterator it = roadAuto.getFeatu...
[truncated message content] |
|
From: <svn...@os...> - 2012-05-01 18:57:55
|
Author: jdeolive
Date: 2012-05-01 11:57:46 -0700 (Tue, 01 May 2012)
New Revision: 38698
Modified:
trunk/docs/src/main/java/org/geotools/jdbc/JDBCExamples.java
trunk/docs/user/library/jdbc/datastore.rst
trunk/docs/user/library/jdbc/h2.rst
trunk/docs/user/library/jdbc/postgis.rst
trunk/docs/user/library/jdbc/spatiallite.rst
Log:
some tweaks to jdbc documentation, pointing at correct code samples
Modified: trunk/docs/src/main/java/org/geotools/jdbc/JDBCExamples.java
===================================================================
--- trunk/docs/src/main/java/org/geotools/jdbc/JDBCExamples.java 2012-05-01 10:03:00 UTC (rev 38697)
+++ trunk/docs/src/main/java/org/geotools/jdbc/JDBCExamples.java 2012-05-01 18:57:46 UTC (rev 38698)
@@ -19,6 +19,30 @@
// h2Example end
}
+void h2AbsPathExample() throws IOException {
+ // h2AbsPathExample start
+ Map<String,Object> params = new HashMap<String,Object>();
+ params.put("dbtype", "h2");
+ params.put("database", "/abs/path/to/geotools");
+
+ DataStore datastore = DataStoreFinder.getDataStore(params);
+ // h2AbsPathExample end
+}
+
+void h2TcpExample() throws IOException {
+ // h2TcpExample start
+ Map<String,Object> params = new HashMap<String,Object>();
+ params.put("dbtype", "h2");
+ params.put("host", "localhost");
+ params.put("port", 9902);
+ params.put("database", "geotools");
+ params.put("passwd", "geotools");
+ params.put("passwd", "geotools");
+
+ DataStore datastore = DataStoreFinder.getDataStore(params);
+ // h2TcpExample end
+}
+
void postgisExample() throws IOException {
// postgisExample start
Map<String,Object> params = new HashMap<String,Object>();
Modified: trunk/docs/user/library/jdbc/datastore.rst
===================================================================
--- trunk/docs/user/library/jdbc/datastore.rst 2012-05-01 10:03:00 UTC (rev 38697)
+++ trunk/docs/user/library/jdbc/datastore.rst 2012-05-01 18:57:46 UTC (rev 38698)
@@ -10,7 +10,7 @@
The process of creating a JDBC data store follows the regular steps of creating any type of datastore. That is defining the parameters to connect to the database in a map, and then creating the data store factory.:
-.. literalinclude:: /../src/main/java/org/geotools/data/SimpleFeatureStoreExamples.java
+.. literalinclude:: /../src/main/java/org/geotools/jdbc/JDBCExamples.java
:language: java
:start-after: // postgisExample start
:end-before: // postgisExample end
Modified: trunk/docs/user/library/jdbc/h2.rst
===================================================================
--- trunk/docs/user/library/jdbc/h2.rst 2012-05-01 10:03:00 UTC (rev 38697)
+++ trunk/docs/user/library/jdbc/h2.rst 2012-05-01 18:57:46 UTC (rev 38698)
@@ -36,7 +36,26 @@
Here is a quick example:
-.. literalinclude:: /../src/main/java/org/geotools/data/SimpleFeatureStoreExamples.java
+.. literalinclude:: /../src/main/java/org/geotools/jdbc/JDBCExamples.java
:language: java
:start-after: // h2Example start
:end-before: // h2Example end
+
+The above will reference a database file named "geotools" located in the current working directory.
+A full path may also be specified:
+
+.. literalinclude:: /../src/main/java/org/geotools/jdbc/JDBCExamples.java
+ :language: java
+ :start-after: // h2AbsPathExample start
+ :end-before: // h2AbsPathExample end
+
+The above examples create a connection to H2 in "embedded" mode. One limitation to this approach is
+that it only allows for a single java process to access the database at any one time. H2 also offers
+a `server mode <http://www.h2database.com/html/tutorial.html#using_server>`_ in which access
+to the underlying database is made via traditional client-server TCP connection, and removes the embedded
+single process restriction:
+
+.. literalinclude:: /../src/main/java/org/geotools/jdbc/JDBCExamples.java
+ :language: java
+ :start-after: // h2TcpExample start
+ :end-before: // h2TcpExample end
Modified: trunk/docs/user/library/jdbc/postgis.rst
===================================================================
--- trunk/docs/user/library/jdbc/postgis.rst 2012-05-01 10:03:00 UTC (rev 38697)
+++ trunk/docs/user/library/jdbc/postgis.rst 2012-05-01 18:57:46 UTC (rev 38698)
@@ -41,7 +41,7 @@
Connect using DataStore finder:
-.. literalinclude:: /../src/main/java/org/geotools/data/SimpleFeatureStoreExamples.java
+.. literalinclude:: /../src/main/java/org/geotools/jdbc/JDBCExamples.java
:language: java
:start-after: // postgisExample start
:end-before: // postgisExample end
Modified: trunk/docs/user/library/jdbc/spatiallite.rst
===================================================================
--- trunk/docs/user/library/jdbc/spatiallite.rst 2012-05-01 10:03:00 UTC (rev 38697)
+++ trunk/docs/user/library/jdbc/spatiallite.rst 2012-05-01 18:57:46 UTC (rev 38698)
@@ -55,9 +55,24 @@
* Native Libraries
- The SpatiaLite data store requires the native libraries for SQLite
- and SpatiaLite to be installed on the system. Precompiled libraries for
- SQLite and SpatiaLite are available.
+ The SpatiaLite datastore ships with its own build of the SQLite and SpatiaLite
+ libraries. The SpatiaLite component has been compiled with GEOS and PROJ support
+ so those libraries need to be installed on the system for the datastore to
+ function. Binaries for a variety of platforms are available at https://www.gaia-gis.it/fossil/libspatialite/index.
+
+ See also:
- * http://www.sqlite.org/download.html
- * http://www.gaia-gis.it/spatialite/binaries.html
+ * http://trac.osgeo.org/proj/
+ * http://trac.osgeo.org/geos/
+
+* Java Environment
+
+ In order to load the native libraries at runtime Java must be told where the libraries live
+ with a system property named "java.library.path". This is specified during java startup::
+
+ java -Djava.library.path=/usr/local/lib ...
+
+ Depending on how the O/S is configured the additional ``LD_LIBRARY_PATH`` (unix/linux) and
+ ``DYLD_LIBRARY_PATH`` (osx) environment variables may need to be set.
+
+
|
|
From: <svn...@os...> - 2012-05-01 10:03:07
|
Author: ang05a
Date: 2012-05-01 03:03:00 -0700 (Tue, 01 May 2012)
New Revision: 38697
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/FeatureTypeMapping.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/PostFilteringMappingFeatureIterator.java
Log:
App-schema isList experimental/temporary solution to subsetting timeseries via filters.
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-04-30 14:22:21 UTC (rev 38696)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/DataAccessMappingFeatureIterator.java 2012-05-01 10:03:00 UTC (rev 38697)
@@ -61,6 +61,7 @@
import org.opengis.feature.type.AttributeType;
import org.opengis.feature.type.FeatureType;
import org.opengis.feature.type.Name;
+import org.opengis.filter.Filter;
import org.opengis.filter.expression.Expression;
import org.opengis.filter.expression.PropertyName;
import org.opengis.filter.identity.FeatureId;
@@ -118,7 +119,13 @@
private boolean isFiltered = false;
private ArrayList<String> filteredFeatures;
+ /**
+ * Temporary/experimental changes for enabling subsetting for isList only.
+ */
+ private Filter listFilter;
+ private List<StepList> listFilterProperties;
+
public DataAccessMappingFeatureIterator(AppSchemaDataAccess store, FeatureTypeMapping mapping,
Query query, boolean isFiltered) throws IOException {
this(store, mapping, query, null);
@@ -821,14 +828,28 @@
Attribute instance = setAttributeValue(target, null, sources.get(0),
attMapping, null, null, selectedProperties.get(attMapping));
if (sources.size() > 1 && instance != null) {
- Object[] values = new Object[sources.size()];
+ List<Object> values = new ArrayList<Object>();
Expression sourceExpr = attMapping.getSourceExpression();
- int i = 0;
- for (Feature source : sources) {
- values[i] = getValue(sourceExpr, source);
- i++;
+ if (listFilter != null
+ && listFilterProperties.contains(attMapping.getTargetXPath())) {
+ for (Feature source : sources) {
+ // HACK HACK HACK
+ // evaluate filter that applies to this list as we want a subset
+ // instead of full result
+ // this is a temporary solution for Bureau of Meteorology
+ // requirement for timePositionList
+ if (listFilter.evaluate(source)) {
+ // only add to subset if filter matches value
+ values.add(getValue(sourceExpr, source));
+ }
+ }
+ } else {
+ // no filter concerning the list
+ for (Feature source : sources) {
+ values.add(getValue(sourceExpr, source));
+ }
}
- String valueString = StringUtils.join(values, " ");
+ String valueString = StringUtils.join(values.iterator(), " ");
StepList fullPath = attMapping.getTargetXPath();
StepList leafPath = fullPath.subList(fullPath.size() - 1, fullPath.size());
if (instance instanceof ComplexAttributeImpl) {
@@ -954,6 +975,8 @@
sourceFeatureIterator = null;
sourceFeatures = null;
filteredFeatures = null;
+ listFilterProperties = null;
+ listFilter = null;
//NC - joining nested atts
for (AttributeMapping attMapping : selectedMapping) {
@@ -1085,4 +1108,12 @@
public boolean isReprojectionCrsEqual(CoordinateReferenceSystem source,CoordinateReferenceSystem target) {
return CRS.equalsIgnoreMetadata(source,target);
}
+
+ public void setListFilter(Filter filter) {
+ listFilter = filter;
+ }
+
+ public void setListFilterProperties(List<StepList> properties) {
+ listFilterProperties = properties;
+ }
}
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-04-30 14:22:21 UTC (rev 38696)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/FeatureTypeMapping.java 2012-05-01 10:03:00 UTC (rev 38697)
@@ -223,11 +223,24 @@
public Name getMappingName() {
return mappingName;
}
-
-
-
-
+
/**
+ * Return list of attribute mappings that are configured as list (isList = true).
+ * @return attribute mappings with isList enabled.
+ */
+ public List<AttributeMapping> getIsListMappings() {
+ List<AttributeMapping> mappings = new ArrayList<AttributeMapping>();
+ AttributeMapping attMapping;
+ for (Iterator<AttributeMapping> it = attributeMappings.iterator(); it.hasNext();) {
+ attMapping = (AttributeMapping) it.next();
+ if (attMapping.isList()) {
+ mappings.add(attMapping);
+ }
+ }
+ return mappings;
+ }
+
+ /**
* Looks up for attribute mappings matching the xpath expression <code>propertyName</code>.
* <p>
* If any step in <code>propertyName</code> has index greater than 1, any mapping for the same
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-04-30 14:22:21 UTC (rev 38696)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/MappingFeatureIteratorFactory.java 2012-05-01 10:03:00 UTC (rev 38697)
@@ -18,23 +18,28 @@
package org.geotools.data.complex;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.logging.Logger;
import org.geotools.data.FeatureSource;
import org.geotools.data.Query;
import org.geotools.data.complex.config.AppSchemaDataAccessConfigurator;
import org.geotools.data.complex.filter.ComplexFilterSplitter;
+import org.geotools.data.complex.filter.XPath;
+import org.geotools.data.complex.filter.XPath.StepList;
import org.geotools.data.joining.JoiningQuery;
import org.geotools.feature.Types;
import org.geotools.filter.FidFilterImpl;
import org.geotools.filter.FilterCapabilities;
-import org.geotools.filter.NestedAttributeExpression;
import org.geotools.filter.visitor.DefaultFilterVisitor;
import org.geotools.jdbc.JDBCFeatureSource;
import org.geotools.jdbc.JDBCFeatureStore;
+import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.filter.Filter;
import org.opengis.filter.expression.PropertyName;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.xml.sax.helpers.NamespaceSupport;
/**
* @author Russell Petty (GeoScience Victoria)
@@ -49,13 +54,76 @@
public class MappingFeatureIteratorFactory {
protected static final Logger LOGGER = org.geotools.util.logging.Logging
.getLogger("org.geotools.data.complex");
+
+ /**
+ * Temporary filter visitor to determine whether the filter concerns any attribute mapping that
+ * has isList enabled. This is because Bureau of Meteorology requires a subset of the property
+ * value to be returned, instead of the full value. This should be a temporary solution. This
+ * won't work with feature chaining at the moment.
+ *
+ * @author Rini Angreani (CSIRO Earth Science and Resource Engineering)
+ *
+ */
+ static class IsListFilterVisitor extends DefaultFilterVisitor {
+ // Attribute mappings that have isList enabled
+ private List<AttributeMapping> listMappings;
+
+ // Filter properties that are configured as isList
+ private List<StepList> listFilterProperties;
+
+ private FeatureTypeMapping mappings;
+
+ public IsListFilterVisitor(List<AttributeMapping> listMappings, FeatureTypeMapping mappings) {
+ this.listMappings = listMappings;
+ this.mappings = mappings;
+ listFilterProperties = new ArrayList<StepList>();
+ }
+
+ @Override
+ public Object visit(PropertyName expression, Object extraData) {
+ AttributeDescriptor root = mappings.getTargetFeature();
+ String attPath = expression.getPropertyName();
+ NamespaceSupport namespaces = mappings.getNamespaces();
+ StepList simplifiedSteps = XPath.steps(root, attPath, namespaces);
+ StepList targetXpath;
+ for (AttributeMapping mapping : listMappings) {
+ targetXpath = mapping.getTargetXPath();
+ if (targetXpath.equals(simplifiedSteps)) {
+ // TODO: support feature chaining too?
+ listFilterProperties.add(targetXpath);
+ }
+ }
+ return extraData;
+ }
+
+ public List<StepList> getListFilterProperties() {
+ return listFilterProperties;
+ }
+ }
+
public static IMappingFeatureIterator getInstance(AppSchemaDataAccess store,
FeatureTypeMapping mapping, Query query, Filter unrolledFilter) throws IOException {
if (mapping instanceof XmlFeatureTypeMapping) {
return new XmlMappingFeatureIterator(store, mapping, query);
}
+
+ // HACK HACK HACK
+ // experimental/temporary solution for isList subsetting by filtering
+ List<AttributeMapping> listMappings = mapping.getIsListMappings();
+ Filter isListFilter = null;
+ List<StepList> listFilterProperties = null;
+ if (!listMappings.isEmpty()) {
+ IsListFilterVisitor listChecker = new IsListFilterVisitor(listMappings, mapping);
+ Filter complexFilter = query.getFilter();
+ complexFilter.accept(listChecker, null);
+ listFilterProperties = listChecker.getListFilterProperties();
+ if (!listFilterProperties.isEmpty()) {
+ isListFilter = AppSchemaDataAccess.unrollFilter(complexFilter, mapping);
+ }
+ }
+ // END OF HACK
boolean isJoining = AppSchemaDataAccessConfigurator.isJoining();
@@ -99,6 +167,14 @@
// 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);
+ // HACK HACK HACK
+ // experimental/temporary solution for isList subsetting by filtering
+ if (isListFilter != null) {
+ ((DataAccessMappingFeatureIterator) iterator).setListFilter(isListFilter);
+ ((DataAccessMappingFeatureIterator) iterator)
+ .setListFilterProperties(listFilterProperties);
+ }
+ // END OF HACK
if (filter != null && filter != Filter.INCLUDE) {
iterator = new PostFilteringMappingFeatureIterator(iterator, filter,
maxFeatures);
@@ -137,6 +213,15 @@
}
}
}
+
+ // HACK HACK HACK
+ // experimental/temporary solution for isList subsetting by filtering
+ if (isListFilter != null && iterator instanceof DataAccessMappingFeatureIterator) {
+ ((DataAccessMappingFeatureIterator) iterator).setListFilter(isListFilter);
+ ((DataAccessMappingFeatureIterator) iterator)
+ .setListFilterProperties(listFilterProperties);
+ }
+ // END OF HACK
return iterator;
}
Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/PostFilteringMappingFeatureIterator.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/PostFilteringMappingFeatureIterator.java 2012-04-30 14:22:21 UTC (rev 38696)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/PostFilteringMappingFeatureIterator.java 2012-05-01 10:03:00 UTC (rev 38697)
@@ -54,8 +54,14 @@
protected Feature getFilteredNext() {
while (delegate.hasNext() && count < maxFeatures) {
Feature feature = delegate.next();
- if (filter.evaluate(feature)) {
- return feature;
+ try {
+ if (filter.evaluate(feature)) {
+ return feature;
+ }
+ } catch (NullPointerException e) {
+ // ignore this exception
+ // this is to cater the case if the attribute has no value and
+ // has been skipped in the delegate DataAccessMappingFeatureIterator
}
}
return null;
|