You can subscribe to this list here.
| 2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(39) |
Dec
(70) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2002 |
Jan
(52) |
Feb
(168) |
Mar
(248) |
Apr
(143) |
May
(418) |
Jun
(558) |
Jul
(702) |
Aug
(311) |
Sep
(141) |
Oct
(350) |
Nov
(172) |
Dec
(182) |
| 2003 |
Jan
(320) |
Feb
(362) |
Mar
(356) |
Apr
(218) |
May
(447) |
Jun
(203) |
Jul
(745) |
Aug
(494) |
Sep
(175) |
Oct
(422) |
Nov
(554) |
Dec
(162) |
| 2004 |
Jan
(217) |
Feb
(353) |
Mar
(228) |
Apr
(407) |
May
(211) |
Jun
(270) |
Jul
(264) |
Aug
(198) |
Sep
(268) |
Oct
(227) |
Nov
(118) |
Dec
(47) |
| 2005 |
Jan
(207) |
Feb
(243) |
Mar
(297) |
Apr
(197) |
May
(281) |
Jun
(166) |
Jul
(164) |
Aug
(92) |
Sep
(155) |
Oct
(196) |
Nov
(189) |
Dec
(114) |
| 2006 |
Jan
(129) |
Feb
(219) |
Mar
(274) |
Apr
(213) |
May
(245) |
Jun
(220) |
Jul
(376) |
Aug
(347) |
Sep
(179) |
Oct
(493) |
Nov
(448) |
Dec
(339) |
| 2007 |
Jan
(304) |
Feb
(273) |
Mar
(237) |
Apr
(186) |
May
(215) |
Jun
(320) |
Jul
(229) |
Aug
(313) |
Sep
(331) |
Oct
(279) |
Nov
(347) |
Dec
(266) |
| 2008 |
Jan
(332) |
Feb
(280) |
Mar
(203) |
Apr
(277) |
May
(301) |
Jun
(356) |
Jul
(292) |
Aug
(203) |
Sep
(277) |
Oct
(142) |
Nov
(210) |
Dec
(239) |
| 2009 |
Jan
(250) |
Feb
(193) |
Mar
(174) |
Apr
(183) |
May
(342) |
Jun
(230) |
Jul
(292) |
Aug
(161) |
Sep
(204) |
Oct
(280) |
Nov
(281) |
Dec
(175) |
| 2010 |
Jan
(113) |
Feb
(106) |
Mar
(199) |
Apr
(166) |
May
(298) |
Jun
(147) |
Jul
(175) |
Aug
(192) |
Sep
(71) |
Oct
(79) |
Nov
(58) |
Dec
(55) |
| 2011 |
Jan
(83) |
Feb
(169) |
Mar
(142) |
Apr
(207) |
May
(311) |
Jun
(183) |
Jul
(218) |
Aug
(190) |
Sep
(158) |
Oct
(197) |
Nov
(93) |
Dec
(74) |
| 2012 |
Jan
(92) |
Feb
(50) |
Mar
(64) |
Apr
(45) |
May
(100) |
Jun
(70) |
Jul
(3) |
Aug
(1) |
Sep
(2) |
Oct
(5) |
Nov
(7) |
Dec
(4) |
| 2013 |
Jan
(6) |
Feb
(2) |
Mar
(2) |
Apr
(4) |
May
(3) |
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
(1) |
Nov
(1) |
Dec
|
| 2014 |
Jan
(2) |
Feb
(2) |
Mar
(2) |
Apr
(3) |
May
(3) |
Jun
(1) |
Jul
|
Aug
(4) |
Sep
|
Oct
(1) |
Nov
(1) |
Dec
|
| 2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
(1) |
Dec
(1) |
| 2016 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
(1) |
Jul
|
Aug
(3) |
Sep
|
Oct
|
Nov
(1) |
Dec
|
| 2017 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <svn...@os...> - 2012-03-09 16:35:58
|
Author: ischneider
Date: 2012-03-09 08:35:47 -0800 (Fri, 09 Mar 2012)
New Revision: 38623
Modified:
trunk/modules/plugin/jdbc/jdbc-teradata/src/test/java/org/geotools/data/teradata/TeradataPrimaryKeyTestSetup.java
Log:
fix columns that were too short
Modified: trunk/modules/plugin/jdbc/jdbc-teradata/src/test/java/org/geotools/data/teradata/TeradataPrimaryKeyTestSetup.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-teradata/src/test/java/org/geotools/data/teradata/TeradataPrimaryKeyTestSetup.java 2012-03-09 16:35:39 UTC (rev 38622)
+++ trunk/modules/plugin/jdbc/jdbc-teradata/src/test/java/org/geotools/data/teradata/TeradataPrimaryKeyTestSetup.java 2012-03-09 16:35:47 UTC (rev 38623)
@@ -46,8 +46,8 @@
protected void createMultiColumnPrimaryKeyTable() throws Exception {
- run("CREATE TABLE \"multi\" ( \"key1\" int NOT NULL, \"key2\" varchar(20) NOT NULL, "
- + "\"name\" varchar(20), geom ST_Geometry)");
+ run("CREATE TABLE \"multi\" ( \"key1\" int NOT NULL, \"key2\" varchar(40) NOT NULL, "
+ + "\"name\" varchar(40), geom ST_Geometry)");
run("INSERT INTO SYSSPATIAL.GEOMETRY_COLUMNS (F_TABLE_CATALOG, F_TABLE_SCHEMA, F_TABLE_NAME, " +
"F_GEOMETRY_COLUMN, COORD_DIMENSION, SRID, GEOM_TYPE) VALUES ('','test','multi', 'geom', " +
"2, " + getDelegate().getSrid4326() + ", 'ST_Geometry')");
|
|
From: <svn...@os...> - 2012-03-09 16:35:48
|
Author: ischneider
Date: 2012-03-09 08:35:39 -0800 (Fri, 09 Mar 2012)
New Revision: 38622
Added:
trunk/modules/plugin/jdbc/jdbc-teradata/src/test/java/org/geotools/data/teradata/TeradataFilterToSQLTest.java
Modified:
trunk/modules/plugin/jdbc/jdbc-teradata/src/main/java/org/geotools/data/teradata/TeradataFilterToSQL.java
Log:
[GEOT-4048] invalid sql generated for query on feature table with composite primary index
Modified: trunk/modules/plugin/jdbc/jdbc-teradata/src/main/java/org/geotools/data/teradata/TeradataFilterToSQL.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-teradata/src/main/java/org/geotools/data/teradata/TeradataFilterToSQL.java 2012-03-08 14:34:00 UTC (rev 38621)
+++ trunk/modules/plugin/jdbc/jdbc-teradata/src/main/java/org/geotools/data/teradata/TeradataFilterToSQL.java 2012-03-09 16:35:39 UTC (rev 38622)
@@ -243,12 +243,14 @@
return false;
}
+ out.write('(');
for (Iterator<PrimaryKeyColumn> it = primaryKey.getColumns().iterator(); it.hasNext();) {
out.write(it.next().getName());
if (it.hasNext()) {
out.write(", ");
}
}
+ out.write(')');
out.write(" IN (SELECT DISTINCT ");
for (Iterator<PrimaryKeyColumn> it = primaryKey.getColumns().iterator(); it.hasNext();) {
Added: trunk/modules/plugin/jdbc/jdbc-teradata/src/test/java/org/geotools/data/teradata/TeradataFilterToSQLTest.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-teradata/src/test/java/org/geotools/data/teradata/TeradataFilterToSQLTest.java (rev 0)
+++ trunk/modules/plugin/jdbc/jdbc-teradata/src/test/java/org/geotools/data/teradata/TeradataFilterToSQLTest.java 2012-03-09 16:35:39 UTC (rev 38622)
@@ -0,0 +1,84 @@
+package org.geotools.data.teradata;
+
+import java.util.Arrays;
+import java.util.logging.Level;
+import org.geotools.data.simple.SimpleFeatureIterator;
+import org.geotools.jdbc.AutoGeneratedPrimaryKeyColumn;
+import org.geotools.jdbc.JDBCTestSetup;
+import org.geotools.jdbc.JDBCTestSupport;
+import org.geotools.jdbc.PrimaryKeyColumn;
+import org.opengis.filter.Filter;
+import org.opengis.filter.FilterFactory;
+import org.opengis.filter.expression.Expression;
+
+/**
+ *
+ * @author Ian Schneider <isc...@op...>
+ */
+public class TeradataFilterToSQLTest extends JDBCTestSupport {
+
+ @Override
+ protected JDBCTestSetup createTestSetup() {
+ return new TeradataFilterToSQLTestSetup();
+ }
+
+ //Ensure that we exercise the composite primary index with bbox sql
+ public void testIt() throws Exception {
+ FilterFactory ff = dataStore.getFilterFactory();
+ Filter bbox = ff.bbox("geometry", 0, 0, 10, 10, "4326");
+ Filter filter = ff.and(bbox,
+ ff.and(
+ ff.equals(ff.literal("intProperty"), ff.literal(5)),
+ ff.equals(ff.literal("doubleProperty"), ff.literal(5))
+ ));
+ ff.equals(ff.literal("intProperty"), ff.literal(5));
+ SimpleFeatureIterator features = dataStore.getFeatureSource("cpi").getFeatures(filter).features();
+ while (features.hasNext()) {
+ features.next();
+ }
+ // if we made it here, we passed
+ }
+
+ private static class TeradataFilterToSQLTestSetup extends TeradataTestSetup {
+
+ @Override
+ protected void setUpData() throws Exception {
+ super.setUpData();
+ // cpi == composite primary index
+ runSafe("DELETE FROM SYSSPATIAL.GEOMETRY_COLUMNS WHERE F_TABLE_NAME = 'cpi'");
+ runSafe("DROP HASH INDEX \"cpi_geometry_idx_idx\"");
+ runSafe("DROP TABLE \"cpi_geometry_idx\"");
+ runSafe("DROP TABLE \"cpi\"");
+
+ run("CREATE TABLE \"cpi\"(" //
+ + "\"id\" not null integer, " //
+ + "\"geometry\" ST_GEOMETRY, " //
+ + "\"intProperty\" int," //
+ + "\"doubleProperty\" double precision, " //
+ + "\"stringProperty\" varchar(200) casespecific) UNIQUE PRIMARY INDEX(intProperty,doubleProperty)");
+ run("INSERT INTO SYSSPATIAL.GEOMETRY_COLUMNS VALUES('"
+ + fixture.getProperty("database") + "', '" + fixture.getProperty("schema")
+ + "', 'cpi', 'geometry', 2, " + srid4326 + ", 'LINESTRING',-180,-90,180,90)");
+ //@todo when things are fixed on teradata side of things, add back primary index
+ run("CREATE MULTISET TABLE \"cpi_geometry_idx\""
+ + " (intProperty INTEGER NOT NULL, doubleProperty double precision not null, cellid INTEGER NOT NULL)"
+ + " UNIQUE PRIMARY INDEX (intProperty,doubleProperty)");
+// + " (id INTEGER NOT NULL, cellid INTEGER NOT NULL)");
+ run("CREATE HASH INDEX cpi_geometry_idx_idx (cellid) ON cpi_geometry_idx ORDER BY (cellid);");
+
+ runSafe("DELETE FROM sysspatial.tessellation WHERE f_table_name = 'cpi'");
+ run("INSERT INTO sysspatial.tessellation VALUES ("
+ + "'geotools',"
+ + "'cpi',"
+ + "'geometry',"
+ + "-180,-90,180,90,"
+ + "1000,1000,3,.01,0"
+ + ")");
+ }
+
+
+ }
+
+
+
+}
|
|
From: <svn...@os...> - 2012-03-08 14:34:12
|
Author: aaime
Date: 2012-03-08 06:34:00 -0800 (Thu, 08 Mar 2012)
New Revision: 38621
Modified:
trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/GranuleDescriptor.java
trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/RasterLayerResponse.java
trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/ReadType.java
trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/Utils.java
trunk/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/ImageMosaicReaderTest.java
Log:
[GEOT-4066] ImageMosaic does not satisfy the specified background values when the request this a hole sitting on the side of the mosaic
Modified: trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/GranuleDescriptor.java
===================================================================
--- trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/GranuleDescriptor.java 2012-03-08 14:33:40 UTC (rev 38620)
+++ trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/GranuleDescriptor.java 2012-03-08 14:34:00 UTC (rev 38621)
@@ -343,9 +343,9 @@
reader = cachedReaderSPI.createReaderInstance();
if(reader == null)
throw new IllegalArgumentException("Unable to get an ImageReader for the provided file "+granuleUrl.toString());
-
+ reader.setInput(inStream);
//get selected level and base level dimensions
- final Rectangle originalDimension = ImageUtilities.getDimension(0,inStream, reader);
+ final Rectangle originalDimension = Utils.getDimension(0, reader);
// build the g2W for this tile, in principle we should get it
// somehow from the tile itself or from the index, but at the moment
@@ -625,6 +625,7 @@
inStream = cachedStreamSPI.createInputStreamInstance(granuleUrl, ImageIO.getUseCache(), ImageIO.getCacheDirectory());
if(inStream==null)
return null;
+
// get a reader and try to cache the relevant SPI
if(cachedReaderSPI==null){
@@ -663,7 +664,7 @@
}
//get selected level and base level dimensions
- final GranuleOverviewLevelDescriptor selectedlevel= getLevel(imageIndex,reader,inStream);
+ final GranuleOverviewLevelDescriptor selectedlevel= getLevel(imageIndex,reader);
// now create the crop grid to world which can be used to decide
@@ -925,13 +926,10 @@
}
}
- private GranuleOverviewLevelDescriptor getLevel(final int index, final ImageReader reader, final ImageInputStream inStream) {
+ private GranuleOverviewLevelDescriptor getLevel(final int index, final ImageReader reader) {
if(reader==null)
- throw new NullPointerException("Null reader passed to the internal GranuleOverviewLevelDescriptor method");
- if(inStream==null)
- throw new NullPointerException("Null stream passed to the internal GranuleOverviewLevelDescriptor method");
-
+ throw new NullPointerException("Null reader passed to the internal GranuleOverviewLevelDescriptor method");
synchronized (granuleLevels) {
if(granuleLevels.containsKey(Integer.valueOf(index)))
return granuleLevels.get(Integer.valueOf(index));
@@ -945,7 +943,7 @@
//
//get selected level and base level dimensions
- final Rectangle levelDimension = ImageUtilities.getDimension(index,inStream, reader);
+ final Rectangle levelDimension = Utils.getDimension(index, reader);
final GranuleOverviewLevelDescriptor baseLevel= granuleLevels.get(0);
final double scaleX=baseLevel.width/(1.0*levelDimension.width);
@@ -993,9 +991,10 @@
reader=cachedReaderSPI.createReaderInstance();
if(reader==null)
throw new IllegalArgumentException("Unable to get an ImageReader for the provided file "+granuleUrl.toString());
+ reader.setInput(inStream);
// call internal method which will close everything
- return getLevel(index, reader, inStream);
+ return getLevel(index, reader);
} catch (IllegalStateException e) {
Modified: trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/RasterLayerResponse.java
===================================================================
--- trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/RasterLayerResponse.java 2012-03-08 14:33:40 UTC (rev 38620)
+++ trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/RasterLayerResponse.java 2012-03-08 14:34:00 UTC (rev 38621)
@@ -20,11 +20,8 @@
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.RenderingHints;
-import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.MultiPixelPackedSampleModel;
@@ -60,6 +57,7 @@
import javax.media.jai.operator.ConstantDescriptor;
import javax.media.jai.operator.FormatDescriptor;
import javax.media.jai.operator.MosaicDescriptor;
+import javax.media.jai.operator.TranslateDescriptor;
import org.apache.commons.io.FilenameUtils;
import org.geotools.coverage.Category;
@@ -1018,11 +1016,14 @@
final Number[] values = ImageUtilities.getBackgroundValues(rasterManager.defaultSM, backgroundValues);
// create a constant image with a proper layout
- final RenderedImage finalImage = ConstantDescriptor.create(
+ RenderedImage finalImage = ConstantDescriptor.create(
Float.valueOf(rasterBounds.width),
Float.valueOf(rasterBounds.height),
values,
null);
+ if (rasterBounds.x != 0 || rasterBounds.y != 0) {
+ finalImage = TranslateDescriptor.create(finalImage, Float.valueOf(rasterBounds.x), Float.valueOf(rasterBounds.y), Interpolation.getInstance(Interpolation.INTERP_NEAREST), null);
+ }
if(rasterManager.defaultCM!=null){
final ImageLayout2 il= new ImageLayout2();
il.setColorModel(rasterManager.defaultCM);
@@ -1165,19 +1166,19 @@
//
// SPECIAL CASE
// 1 single tile, we try not do a mosaic.
+ final ROI[] sourceRoi = visitor.sourceRoi;
if(visitor.granulesNumber==1 && Utils.OPTIMIZE_CROP){
// the roi is exactly equal to the
final ROI roi = visitor.rois.get(0);
- Rectangle bounds = toRectangle(roi.getAsShape());
+ Rectangle bounds = Utils.toRectangle(roi.getAsShape());
if (bounds != null) {
- final RenderedImage image= visitor.getSourcesAsArray()[0];
- final Rectangle imageBounds= PlanarImage.wrapRenderedImage(image).getBounds();
+ RenderedImage image= visitor.getSourcesAsArray()[0];
+ Rectangle imageBounds= PlanarImage.wrapRenderedImage(image).getBounds();
if(imageBounds.equals(bounds)){
- // do we need to crop
- if(!imageBounds.equals(rasterBounds)){
+ // do we need to crop? (image is bigger than requested?)
+ if(!rasterBounds.contains(imageBounds)){
// we have to crop
-
XRectangle2D.intersect(imageBounds, rasterBounds, imageBounds);
if(imageBounds.isEmpty()){
@@ -1188,15 +1189,28 @@
ImageWorker iw = new ImageWorker(image);
iw.setRenderingHints(localHints);
iw.crop(imageBounds.x, imageBounds.y, imageBounds.width, imageBounds.height);
- return iw.getRenderedImage();
+
+ image = iw.getRenderedImage();
+ imageBounds = PlanarImage.wrapRenderedImage(image).getBounds();
}
+
+ // and, do we need to add a border around the image?
+ if(!imageBounds.contains(rasterBounds)) {
+ image = MosaicDescriptor.create(
+ new RenderedImage[] {image},
+ request.isBlend()? MosaicDescriptor.MOSAIC_TYPE_BLEND: MosaicDescriptor.MOSAIC_TYPE_OVERLAY,
+ (alphaIn || visitor.doInputTransparency) ? visitor.alphaChannels : null, sourceRoi,
+ visitor.sourceThreshold,
+ backgroundValues,
+ localHints);
+ }
+
return image;
}
}
}
- final ROI[] sourceRoi = visitor.sourceRoi;
final RenderedImage mosaic = MosaicDescriptor.create(
visitor.getSourcesAsArray(),
request.isBlend()? MosaicDescriptor.MOSAIC_TYPE_BLEND: MosaicDescriptor.MOSAIC_TYPE_OVERLAY,
@@ -1231,91 +1245,6 @@
}
/**
- * Checks if the Shape equates to a Rectangle, if it does it performs a conversion, otherwise
- * returns null
- * @param shape
- * @return
- */
- Rectangle toRectangle(Shape shape) {
- if(shape instanceof Rectangle) {
- return (Rectangle) shape;
- }
-
- if(shape == null) {
- return null;
- }
-
- // check if it's equivalent to a rectangle
- PathIterator iter = shape.getPathIterator(new AffineTransform());
- double[] coords = new double[2];
-
- // not enough points?
- if(iter.isDone()) {
- return null;
- }
-
- // get the first and init the data structures
- iter.next();
- int action = iter.currentSegment(coords);
- if(action != PathIterator.SEG_MOVETO && action != PathIterator.SEG_LINETO) {
- return null;
- }
- double minx = coords[0];
- double miny = coords[1];
- double maxx = minx;
- double maxy = miny;
- double prevx = minx;
- double prevy = miny;
- int i = 0;
-
- // at most 4 steps, if more it's not a strict rectangle
- for (; i < 4 && !iter.isDone(); i++) {
- iter.next();
- action = iter.currentSegment(coords);
-
- if(action == PathIterator.SEG_CLOSE) {
- break;
- }
- if(action != PathIterator.SEG_LINETO) {
- return null;
- }
-
- // check orthogonal step (x does not change and y does, or vice versa)
- double x = coords[0];
- double y = coords[1];
- if(!(prevx == x && prevy != y) &&
- !(prevx != x && prevy == y)) {
- return null;
- }
-
- // update mins and maxes
- if(x < minx) {
- minx = x;
- } else if(x > maxx) {
- maxx = x;
- }
- if(y < miny) {
- miny = y;
- } else if(y > maxy) {
- maxy = y;
- }
-
- // keep track of prev step
- prevx = x;
- prevy = y;
- }
-
- // if more than 4 other points it's not a standard rectangle
- iter.next();
- if(!iter.isDone() || i != 3) {
- return null;
- }
-
- // turn it into a rectangle
- return new Rectangle2D.Double(minx, miny, maxx - minx, maxy - miny).getBounds();
- }
-
- /**
* This method is responsible for creating a coverage from the supplied {@link RenderedImage}.
*
* @param image
@@ -1424,12 +1353,11 @@
null
).geophysics(true);
}
-
return coverageFactory.create(
rasterManager.getCoverageIdentifier(),
image,
new GridGeometry2D(
- new GridEnvelope2D(PlanarImage.wrapRenderedImage(image).getBounds()),
+ new GridEnvelope2D(PlanarImage.wrapRenderedImage(image).getBounds()),
PixelInCell.CELL_CORNER,
finalGridToWorldCorner,
this.mosaicBBox.getCoordinateReferenceSystem(),
Modified: trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/ReadType.java
===================================================================
--- trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/ReadType.java 2012-03-08 14:33:40 UTC (rev 38620)
+++ trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/ReadType.java 2012-03-08 14:34:00 UTC (rev 38621)
@@ -143,6 +143,7 @@
// check input stream
final ImageInputStream inStream=(ImageInputStream) reader.getInput();
// read data
+ inStream.seek(0);
final RenderedOp raster = ImageReadDescriptor.create(
inStream,
imageIndex,
Modified: trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/Utils.java
===================================================================
--- trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/Utils.java 2012-03-08 14:33:40 UTC (rev 38620)
+++ trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/Utils.java 2012-03-08 14:34:00 UTC (rev 38621)
@@ -17,7 +17,11 @@
package org.geotools.gce.imagemosaic;
import java.awt.Color;
+import java.awt.Rectangle;
+import java.awt.Shape;
import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.RenderedImage;
@@ -40,6 +44,7 @@
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Properties;
@@ -48,6 +53,9 @@
import java.util.logging.Level;
import java.util.logging.Logger;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.stream.ImageInputStream;
import javax.media.jai.Histogram;
import javax.media.jai.RasterFactory;
import javax.media.jai.remote.SerializableRenderedImage;
@@ -71,6 +79,8 @@
import org.geotools.gce.imagemosaic.catalogbuilder.CatalogBuilderConfiguration;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.operation.matrix.XAffineTransform;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
import org.geotools.util.Converters;
import org.geotools.util.Utilities;
@@ -501,6 +511,64 @@
}
/**
+ * Look for an {@link ImageReader} instance that is able to read the
+ * provided {@link ImageInputStream}, which must be non null.
+ *
+ * <p>
+ * In case no reader is found, <code>null</code> is returned.
+ *
+ * @param inStream
+ * an instance of {@link ImageInputStream} for which we need to
+ * find a suitable {@link ImageReader}.
+ * @return a suitable instance of {@link ImageReader} or <code>null</code>
+ * if one cannot be found.
+ */
+ static ImageReader getReader(final ImageInputStream inStream) {
+ Utilities.ensureNonNull("inStream", inStream);
+ // get a reader
+ inStream.mark();
+ final Iterator<ImageReader> readersIt = ImageIO
+ .getImageReaders(inStream);
+ if (!readersIt.hasNext()) {
+ return null;
+ }
+ return readersIt.next();
+ }
+
+ /**
+ * Retrieves the dimensions of the {@link RenderedImage} at index
+ * <code>imageIndex</code> for the provided {@link ImageReader} and
+ * {@link ImageInputStream}.
+ *
+ * <p>
+ * Notice that none of the input parameters can be <code>null</code> or a
+ * {@link NullPointerException} will be thrown. Morevoer the
+ * <code>imageIndex</code> cannot be negative or an
+ * {@link IllegalArgumentException} will be thrown.
+ *
+ * @param imageIndex
+ * the index of the image to get the dimensions for.
+ * @param inStream
+ * the {@link ImageInputStream} to use as an input
+ * @param reader
+ * the {@link ImageReader} to decode the image dimensions.
+ * @return a {@link Rectangle} that contains the dimensions for the image at
+ * index <code>imageIndex</code>
+ * @throws IOException
+ * in case the {@link ImageReader} or the
+ * {@link ImageInputStream} fail.
+ */
+ static Rectangle getDimension(final int imageIndex,final ImageReader reader)
+ throws IOException {
+ Utilities.ensureNonNull("reader", reader);
+ if (imageIndex < 0)
+ throw new IllegalArgumentException(Errors.format(
+ ErrorKeys.INDEX_OUT_OF_BOUNDS_$1, imageIndex));
+ return new Rectangle(0, 0, reader.getWidth(imageIndex), reader
+ .getHeight(imageIndex));
+ }
+
+ /**
* Default priority for the underlying {@link Thread}.
*/
public static final int DEFAULT_PRIORITY = Thread.NORM_PRIORITY;
@@ -1134,4 +1202,89 @@
return true;
return false;
}
+
+ /**
+ * Checks if the Shape equates to a Rectangle, if it does it performs a conversion, otherwise
+ * returns null
+ * @param shape
+ * @return
+ */
+ static Rectangle toRectangle(Shape shape) {
+ if(shape instanceof Rectangle) {
+ return (Rectangle) shape;
+ }
+
+ if(shape == null) {
+ return null;
+ }
+
+ // check if it's equivalent to a rectangle
+ PathIterator iter = shape.getPathIterator(new AffineTransform());
+ double[] coords = new double[2];
+
+ // not enough points?
+ if(iter.isDone()) {
+ return null;
+ }
+
+ // get the first and init the data structures
+ iter.next();
+ int action = iter.currentSegment(coords);
+ if(action != PathIterator.SEG_MOVETO && action != PathIterator.SEG_LINETO) {
+ return null;
+ }
+ double minx = coords[0];
+ double miny = coords[1];
+ double maxx = minx;
+ double maxy = miny;
+ double prevx = minx;
+ double prevy = miny;
+ int i = 0;
+
+ // at most 4 steps, if more it's not a strict rectangle
+ for (; i < 4 && !iter.isDone(); i++) {
+ iter.next();
+ action = iter.currentSegment(coords);
+
+ if(action == PathIterator.SEG_CLOSE) {
+ break;
+ }
+ if(action != PathIterator.SEG_LINETO) {
+ return null;
+ }
+
+ // check orthogonal step (x does not change and y does, or vice versa)
+ double x = coords[0];
+ double y = coords[1];
+ if(!(prevx == x && prevy != y) &&
+ !(prevx != x && prevy == y)) {
+ return null;
+ }
+
+ // update mins and maxes
+ if(x < minx) {
+ minx = x;
+ } else if(x > maxx) {
+ maxx = x;
+ }
+ if(y < miny) {
+ miny = y;
+ } else if(y > maxy) {
+ maxy = y;
+ }
+
+ // keep track of prev step
+ prevx = x;
+ prevy = y;
+ }
+
+ // if more than 4 other points it's not a standard rectangle
+ iter.next();
+ if(!iter.isDone() || i != 3) {
+ return null;
+ }
+
+ // turn it into a rectangle
+ return new Rectangle2D.Double(minx, miny, maxx - minx, maxy - miny).getBounds();
+ }
}
Modified: trunk/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/ImageMosaicReaderTest.java
===================================================================
--- trunk/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/ImageMosaicReaderTest.java 2012-03-08 14:33:40 UTC (rev 38620)
+++ trunk/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/ImageMosaicReaderTest.java 2012-03-08 14:34:00 UTC (rev 38621)
@@ -19,6 +19,9 @@
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileNotFoundException;
@@ -34,7 +37,9 @@
import java.util.TimeZone;
import java.util.logging.Logger;
+import javax.imageio.ImageIO;
import javax.media.jai.PlanarImage;
+import javax.media.jai.iterator.RectIterFactory;
import javax.media.jai.widget.ScrollingImagePanel;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
@@ -52,6 +57,7 @@
import org.geotools.coverage.grid.io.OverviewPolicy;
import org.geotools.coverage.grid.io.UnknownFormat;
import org.geotools.factory.Hints;
+import org.geotools.geometry.Envelope2D;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.parameter.Parameter;
import org.geotools.referencing.CRS;
@@ -61,8 +67,8 @@
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
+import org.opengis.geometry.Envelope;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.parameter.GeneralParameterValue;
import org.opengis.parameter.ParameterValue;
@@ -869,7 +875,80 @@
checkCoverage(reader, new GeneralParameterValue[] { gg, outTransp },title);
}
+
+ @Test
+ public void testRequestInHole() throws Exception {
+ final AbstractGridFormat format = getFormat(rgbAURL);
+ final ImageMosaicReader reader = getReader(rgbAURL, format);
+ assertNotNull(reader);
+
+ // ask to extract an area that is inside the coverage bbox, but in a hole (no data)
+ final ParameterValue<GridGeometry2D> ggp = AbstractGridFormat.READ_GRIDGEOMETRY2D.createValue();
+ Envelope2D env = new Envelope2D(reader.getCrs(), 500000, 3200000, 1000, 1000);
+ GridGeometry2D gg = new GridGeometry2D(new GridEnvelope2D(0, 0, 100, 100), (Envelope) env);
+ ggp.setValue(gg);
+
+ // red background
+ final ParameterValue<double[]> bgp = ImageMosaicFormat.BACKGROUND_VALUES.createValue();
+ bgp.setValue(new double[] {255, 0, 0, 255});
+
+ // read and check we actually got a coverage in the requested area
+ GridCoverage2D coverage = reader.read(new GeneralParameterValue[] {ggp, bgp});
+ assertNotNull(coverage);
+ assertTrue(coverage.getEnvelope2D().intersects((Rectangle2D) env));
+
+ // and that the color is the expected one given the background values provided
+ RenderedImage ri = coverage.getRenderedImage();
+ int[] pixel = new int[4];
+ Raster tile = ri.getTile(ri.getMinTileX() + 1, ri.getMinTileY() + 1);
+ tile.getPixel(tile.getMinX(), tile.getMinY(), pixel);
+ assertEquals(255, pixel[0]);
+ assertEquals(0, pixel[1]);
+ assertEquals(0, pixel[2]);
+ assertEquals(255, pixel[3]);
+ }
+
+ @Test
+ public void testRequestInOut() throws Exception {
+ final AbstractGridFormat format = getFormat(rgbAURL);
+ final ImageMosaicReader reader = getReader(rgbAURL, format);
+
+ assertNotNull(reader);
+
+ // ask to extract an area that is inside the coverage bbox, so that the area is partly
+ // inside the raster, and partly outside
+ final ParameterValue<GridGeometry2D> ggp = AbstractGridFormat.READ_GRIDGEOMETRY2D.createValue();
+ Envelope2D env = new Envelope2D(reader.getCrs(), 64887, 2499342, 646897 - 64887 , 3155705 - 2499342);
+ GridGeometry2D gg = new GridGeometry2D(new GridEnvelope2D(0, 0, 100, 100), (Envelope) env);
+ ggp.setValue(gg);
+
+ // red background
+ final ParameterValue<double[]> bgp = ImageMosaicFormat.BACKGROUND_VALUES.createValue();
+ bgp.setValue(new double[] {255, 0, 0, 255});
+
+ // read and check we actually got a coverage in the requested area
+ GridCoverage2D coverage = reader.read(new GeneralParameterValue[] {ggp, bgp});
+ assertNotNull(coverage);
+ System.out.println(coverage.getEnvelope2D());
+ System.out.println(env);
+ assertTrue(coverage.getEnvelope2D().contains((Rectangle2D) env));
+
+ // and that the color is the expected one given the background values provided
+ RenderedImage ri = coverage.getRenderedImage();
+ ImageIO.write(ri, "PNG", new File("/tmp/mix.png"));
+ System.out.println(ri.getNumXTiles());
+ System.out.println(ri.getNumYTiles());
+ int[] pixel = new int[4];
+ Raster tile = ri.getTile(ri.getMinTileX() + ri.getNumXTiles() - 1,
+ ri.getMinTileY() + ri.getNumYTiles() - 1);
+ tile.getPixel(tile.getWidth() / 2, tile.getHeight() / 2, pixel);
+ assertEquals(255, pixel[0]);
+ assertEquals(0, pixel[1]);
+ assertEquals(0, pixel[2]);
+ assertEquals(255, pixel[3]);
+ }
+
/**
* @param args
*/
|
|
From: <svn...@os...> - 2012-03-08 14:33:52
|
Author: aaime
Date: 2012-03-08 06:33:40 -0800 (Thu, 08 Mar 2012)
New Revision: 38620
Modified:
trunk/modules/library/coverage/src/main/java/org/geotools/image/palette/CustomPaletteBuilder.java
trunk/modules/library/coverage/src/test/java/org/geotools/image/palette/CustomPaletteBuilderTest.java
Log:
[GEOT-4065] CustomPaletteBuilder may fail on images with shifted tile origin
Modified: trunk/modules/library/coverage/src/main/java/org/geotools/image/palette/CustomPaletteBuilder.java
===================================================================
--- trunk/modules/library/coverage/src/main/java/org/geotools/image/palette/CustomPaletteBuilder.java 2012-03-08 14:33:20 UTC (rev 38619)
+++ trunk/modules/library/coverage/src/main/java/org/geotools/image/palette/CustomPaletteBuilder.java 2012-03-08 14:33:40 UTC (rev 38620)
@@ -173,12 +173,18 @@
int minx = r.getMinX();
int miny = r.getMinY();
+ int sampleModelTx = r.getSampleModelTranslateX();
+ int sampleModelTy = r.getSampleModelTranslateY();
+
minx = minx < minx_ ? minx_ : minx;
miny = miny < miny_ ? miny_ : miny;
int maxx = minx + tileW;
int maxy = miny + tileH;
- maxx = maxx > maxx_ ? maxx_ : maxx;
- maxy = maxy > maxy_ ? maxy_ : maxy;
+ int maxxR = maxx + sampleModelTx;
+ int maxyR = maxy + sampleModelTy;
+ maxx = maxx > maxx_ ? (maxx_ > maxxR ? maxxR : maxx_) : (maxx > maxxR ? maxxR : maxx);
+ maxy = maxy > maxy_ ? (maxy_ > maxyR ? maxyR : maxy_) : (maxy > maxyR ? maxyR : maxy);
+
actualWidth = maxx - minx;
actualHeight = maxy - miny;
for (int j = miny, jj = dstTempY; j < maxy; j++, jj++) {
@@ -316,12 +322,17 @@
int minx = r.getMinX();
int miny = r.getMinY();
+ int sampleModelTx = r.getSampleModelTranslateX();
+ int sampleModelTy = r.getSampleModelTranslateY();
minx = minx < minx_ ? minx_ : minx;
miny = miny < miny_ ? miny_ : miny;
int maxx = minx + tileW;
int maxy = miny + tileH;
- maxx = maxx > maxx_ ? maxx_ : maxx;
- maxy = maxy > maxy_ ? maxy_ : maxy;
+ int maxxR = maxx + sampleModelTx;
+ int maxyR = maxy + sampleModelTy;
+ maxx = maxx > maxx_ ? (maxx_ > maxxR ? maxxR : maxx_) : (maxx > maxxR ? maxxR : maxx);
+ maxy = maxy > maxy_ ? (maxy_ > maxyR ? maxyR : maxy_) : (maxy > maxyR ? maxyR : maxy);
+
for (int j = miny; j < maxy; j++) {
if ((subsampley > 1) && ((j % subsampley) != 0)) {
continue;
Modified: trunk/modules/library/coverage/src/test/java/org/geotools/image/palette/CustomPaletteBuilderTest.java
===================================================================
--- trunk/modules/library/coverage/src/test/java/org/geotools/image/palette/CustomPaletteBuilderTest.java 2012-03-08 14:33:20 UTC (rev 38619)
+++ trunk/modules/library/coverage/src/test/java/org/geotools/image/palette/CustomPaletteBuilderTest.java 2012-03-08 14:33:40 UTC (rev 38620)
@@ -19,20 +19,25 @@
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.RenderedImage;
+import java.awt.image.SampleModel;
import javax.media.jai.ImageLayout;
import javax.media.jai.JAI;
import javax.media.jai.OperationDescriptor;
import javax.media.jai.ParameterBlockJAI;
import javax.media.jai.PlanarImage;
+import javax.media.jai.TiledImage;
import junit.framework.TestCase;
import org.geotools.image.ImageWorker;
import org.junit.Test;
+import com.sun.media.jai.codecimpl.util.RasterFactory;
+
/**
* Testing custom code for color reduction.
*
@@ -98,6 +103,26 @@
}
+ @Test
+ public void testTranslatedImage() {
+ BufferedImage bi = new BufferedImage(256, 256, BufferedImage.TYPE_BYTE_GRAY);
+ TiledImage image = new TiledImage(0, 0, 256, 256, 1, 1, bi.getSampleModel().createCompatibleSampleModel(256, 256), bi.getColorModel());
+ Graphics g = image.createGraphics();
+ g.setColor(Color.WHITE);
+ g.fillRect(0, 0, 20, 20);
+ g.setColor(new Color(20, 20, 20)); // A dark gray
+ g.fillRect(20, 20, 20, 20);
+ g.setColor(new Color(200, 200, 200)); // A light gray
+ g.fillRect(0, 20, 20, 20);
+ g.dispose();
+ CustomPaletteBuilder builder = new CustomPaletteBuilder(image, 256, 1, 1, 1);
+ RenderedImage indexed = builder.buildPalette().getIndexedImage();
+ assertTrue(indexed.getColorModel() instanceof IndexColorModel);
+ IndexColorModel icm = (IndexColorModel) indexed.getColorModel();
+ assertEquals(4, icm.getMapSize()); //Black background, white fill, light gray fill, dark gray fill = 4 colors
+
+ }
+
@Test
public void testFourColor() {
|
|
From: <svn...@os...> - 2012-03-08 14:33:31
|
Author: aaime
Date: 2012-03-08 06:33:20 -0800 (Thu, 08 Mar 2012)
New Revision: 38619
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-4064] ImageWorker.affine misbehaves in case of chained, inverted transforms
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-03-08 14:14:48 UTC (rev 38618)
+++ trunk/modules/library/coverage/src/main/java/org/geotools/image/ImageWorker.java 2012-03-08 14:33:20 UTC (rev 38619)
@@ -2863,6 +2863,7 @@
// did it become a identity after the combination?
if(!hasScaleX && !hasScaleY && !hasShearX && !hasShearY && !hasTranslateX && !hasTranslateY) {
+ this.image = source;
return this;
}
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-03-08 14:14:48 UTC (rev 38618)
+++ trunk/modules/library/coverage/src/test/java/org/geotools/image/ImageWorkerTest.java 2012-03-08 14:33:20 UTC (rev 38619)
@@ -26,6 +26,7 @@
import java.awt.Color;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
@@ -836,4 +837,26 @@
assertEquals(Math.round(inputCM.getAlpha(i) * 0.5), outputCM.getAlpha(i));
}
}
+
+ @Test
+ public void testOptimizeAffine() throws Exception {
+ BufferedImage bi = new BufferedImage(100, 100, BufferedImage.TYPE_3BYTE_BGR);
+ ImageWorker iw = new ImageWorker(bi);
+
+ // apply straight translation
+ AffineTransform at = AffineTransform.getTranslateInstance(100, 100);
+ iw.affine(at, null, null);
+ RenderedImage t1 = iw.getRenderedImage();
+ assertEquals(100, t1.getMinX());
+ assertEquals(100, t1.getMinY());
+
+ // now go back
+ AffineTransform atInverse = AffineTransform.getTranslateInstance(-100, -100);
+ iw.affine(atInverse, null, null);
+ RenderedImage t2 = iw.getRenderedImage();
+ assertEquals(0, t2.getMinX());
+ assertEquals(0, t2.getMinY());
+ assertSame(bi, t2);
+
+ }
}
|
|
From: <svn...@os...> - 2012-03-08 14:14:59
|
Author: aaime
Date: 2012-03-08 06:14:48 -0800 (Thu, 08 Mar 2012)
New Revision: 38618
Modified:
branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/GranuleDescriptor.java
branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/RasterLayerResponse.java
branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/ReadType.java
branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/Utils.java
branches/2.7.x/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/ImageMosaicReaderTest.java
Log:
[GEOT-4066] ImageMosaic does not satisfy the specified background values when the request this a hole sitting on the side of the mosaic
Modified: branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/GranuleDescriptor.java
===================================================================
--- branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/GranuleDescriptor.java 2012-03-08 14:14:21 UTC (rev 38617)
+++ branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/GranuleDescriptor.java 2012-03-08 14:14:48 UTC (rev 38618)
@@ -342,9 +342,9 @@
reader = cachedReaderSPI.createReaderInstance();
if(reader == null)
throw new IllegalArgumentException("Unable to get an ImageReader for the provided file "+granuleUrl.toString());
-
+ reader.setInput(inStream);
//get selected level and base level dimensions
- final Rectangle originalDimension = Utils.getDimension(0,inStream, reader);
+ final Rectangle originalDimension = Utils.getDimension(0, reader);
// build the g2W for this tile, in principle we should get it
// somehow from the tile itself or from the index, but at the moment
@@ -624,6 +624,7 @@
inStream = cachedStreamSPI.createInputStreamInstance(granuleUrl, ImageIO.getUseCache(), ImageIO.getCacheDirectory());
if(inStream==null)
return null;
+
// get a reader and try to cache the relevant SPI
if(cachedReaderSPI==null){
@@ -662,7 +663,7 @@
}
//get selected level and base level dimensions
- final GranuleOverviewLevelDescriptor selectedlevel= getLevel(imageIndex,reader,inStream);
+ final GranuleOverviewLevelDescriptor selectedlevel= getLevel(imageIndex,reader);
// now create the crop grid to world which can be used to decide
@@ -924,13 +925,10 @@
}
}
- private GranuleOverviewLevelDescriptor getLevel(final int index, final ImageReader reader, final ImageInputStream inStream) {
+ private GranuleOverviewLevelDescriptor getLevel(final int index, final ImageReader reader) {
if(reader==null)
- throw new NullPointerException("Null reader passed to the internal GranuleOverviewLevelDescriptor method");
- if(inStream==null)
- throw new NullPointerException("Null stream passed to the internal GranuleOverviewLevelDescriptor method");
-
+ throw new NullPointerException("Null reader passed to the internal GranuleOverviewLevelDescriptor method");
synchronized (granuleLevels) {
if(granuleLevels.containsKey(Integer.valueOf(index)))
return granuleLevels.get(Integer.valueOf(index));
@@ -944,7 +942,7 @@
//
//get selected level and base level dimensions
- final Rectangle levelDimension = Utils.getDimension(index,inStream, reader);
+ final Rectangle levelDimension = Utils.getDimension(index, reader);
final GranuleOverviewLevelDescriptor baseLevel= granuleLevels.get(0);
final double scaleX=baseLevel.width/(1.0*levelDimension.width);
@@ -992,9 +990,10 @@
reader=cachedReaderSPI.createReaderInstance();
if(reader==null)
throw new IllegalArgumentException("Unable to get an ImageReader for the provided file "+granuleUrl.toString());
+ reader.setInput(inStream);
// call internal method which will close everything
- return getLevel(index, reader, inStream);
+ return getLevel(index, reader);
} catch (IllegalStateException e) {
Modified: branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/RasterLayerResponse.java
===================================================================
--- branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/RasterLayerResponse.java 2012-03-08 14:14:21 UTC (rev 38617)
+++ branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/RasterLayerResponse.java 2012-03-08 14:14:48 UTC (rev 38618)
@@ -23,11 +23,8 @@
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.RenderingHints;
-import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.MultiPixelPackedSampleModel;
@@ -63,6 +60,7 @@
import javax.media.jai.operator.ConstantDescriptor;
import javax.media.jai.operator.FormatDescriptor;
import javax.media.jai.operator.MosaicDescriptor;
+import javax.media.jai.operator.TranslateDescriptor;
import org.apache.commons.io.FilenameUtils;
import org.geotools.coverage.Category;
@@ -1019,11 +1017,14 @@
final Number[] values = Utils.getBackgroundValues(rasterManager.defaultSM, backgroundValues);
// create a constant image with a proper layout
- final RenderedImage finalImage = ConstantDescriptor.create(
+ RenderedImage finalImage = ConstantDescriptor.create(
Float.valueOf(rasterBounds.width),
Float.valueOf(rasterBounds.height),
values,
null);
+ if (rasterBounds.x != 0 || rasterBounds.y != 0) {
+ finalImage = TranslateDescriptor.create(finalImage, Float.valueOf(rasterBounds.x), Float.valueOf(rasterBounds.y), Interpolation.getInstance(Interpolation.INTERP_NEAREST), null);
+ }
if(rasterManager.defaultCM!=null){
final ImageLayout2 il= new ImageLayout2();
il.setColorModel(rasterManager.defaultCM);
@@ -1165,19 +1166,19 @@
//
// SPECIAL CASE
// 1 single tile, we try not do a mosaic.
+ final ROI[] sourceRoi = visitor.sourceRoi;
if(visitor.granulesNumber==1 && Utils.OPTIMIZE_CROP){
// the roi is exactly equal to the
final ROI roi = visitor.rois.get(0);
- Rectangle bounds = toRectangle(roi.getAsShape());
+ Rectangle bounds = Utils.toRectangle(roi.getAsShape());
if (bounds != null) {
- final RenderedImage image= visitor.getSourcesAsArray()[0];
- final Rectangle imageBounds= PlanarImage.wrapRenderedImage(image).getBounds();
+ RenderedImage image= visitor.getSourcesAsArray()[0];
+ Rectangle imageBounds= PlanarImage.wrapRenderedImage(image).getBounds();
if(imageBounds.equals(bounds)){
- // do we need to crop
- if(!imageBounds.equals(rasterBounds)){
+ // do we need to crop? (image is bigger than requested?)
+ if(!rasterBounds.contains(imageBounds)){
// we have to crop
-
XRectangle2D.intersect(imageBounds, rasterBounds, imageBounds);
if(imageBounds.isEmpty()){
@@ -1188,15 +1189,28 @@
ImageWorker iw = new ImageWorker(image);
iw.setRenderingHints(localHints);
iw.crop(imageBounds.x, imageBounds.y, imageBounds.width, imageBounds.height);
- return iw.getRenderedImage();
+
+ image = iw.getRenderedImage();
+ imageBounds = PlanarImage.wrapRenderedImage(image).getBounds();
}
+
+ // and, do we need to add a border around the image?
+ if(!imageBounds.contains(rasterBounds)) {
+ image = MosaicDescriptor.create(
+ new RenderedImage[] {image},
+ request.isBlend()? MosaicDescriptor.MOSAIC_TYPE_BLEND: MosaicDescriptor.MOSAIC_TYPE_OVERLAY,
+ (alphaIn || visitor.doInputTransparency) ? visitor.alphaChannels : null, sourceRoi,
+ visitor.sourceThreshold,
+ backgroundValues,
+ localHints);
+ }
+
return image;
}
}
}
- final ROI[] sourceRoi = visitor.sourceRoi;
final RenderedImage mosaic = MosaicDescriptor.create(
visitor.getSourcesAsArray(),
request.isBlend()? MosaicDescriptor.MOSAIC_TYPE_BLEND: MosaicDescriptor.MOSAIC_TYPE_OVERLAY,
@@ -1231,91 +1245,6 @@
}
/**
- * Checks if the Shape equates to a Rectangle, if it does it performs a conversion, otherwise
- * returns null
- * @param shape
- * @return
- */
- Rectangle toRectangle(Shape shape) {
- if(shape instanceof Rectangle) {
- return (Rectangle) shape;
- }
-
- if(shape == null) {
- return null;
- }
-
- // check if it's equivalent to a rectangle
- PathIterator iter = shape.getPathIterator(new AffineTransform());
- double[] coords = new double[2];
-
- // not enough points?
- if(iter.isDone()) {
- return null;
- }
-
- // get the first and init the data structures
- iter.next();
- int action = iter.currentSegment(coords);
- if(action != PathIterator.SEG_MOVETO && action != PathIterator.SEG_LINETO) {
- return null;
- }
- double minx = coords[0];
- double miny = coords[1];
- double maxx = minx;
- double maxy = miny;
- double prevx = minx;
- double prevy = miny;
- int i = 0;
-
- // at most 4 steps, if more it's not a strict rectangle
- for (; i < 4 && !iter.isDone(); i++) {
- iter.next();
- action = iter.currentSegment(coords);
-
- if(action == PathIterator.SEG_CLOSE) {
- break;
- }
- if(action != PathIterator.SEG_LINETO) {
- return null;
- }
-
- // check orthogonal step (x does not change and y does, or vice versa)
- double x = coords[0];
- double y = coords[1];
- if(!(prevx == x && prevy != y) &&
- !(prevx != x && prevy == y)) {
- return null;
- }
-
- // update mins and maxes
- if(x < minx) {
- minx = x;
- } else if(x > maxx) {
- maxx = x;
- }
- if(y < miny) {
- miny = y;
- } else if(y > maxy) {
- maxy = y;
- }
-
- // keep track of prev step
- prevx = x;
- prevy = y;
- }
-
- // if more than 4 other points it's not a standard rectangle
- iter.next();
- if(!iter.isDone() || i != 3) {
- return null;
- }
-
- // turn it into a rectangle
- return new Rectangle2D.Double(minx, miny, maxx - minx, maxy - miny).getBounds();
- }
-
- /**
* This method is responsible for creating a coverage from the supplied {@link RenderedImage}.
*
* @param image
@@ -1424,12 +1353,11 @@
null
).geophysics(true);
}
-
return coverageFactory.create(
rasterManager.getCoverageIdentifier(),
image,
new GridGeometry2D(
- new GridEnvelope2D(PlanarImage.wrapRenderedImage(image).getBounds()),
+ new GridEnvelope2D(PlanarImage.wrapRenderedImage(image).getBounds()),
PixelInCell.CELL_CORNER,
finalGridToWorldCorner,
this.mosaicBBox.getCoordinateReferenceSystem(),
Modified: branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/ReadType.java
===================================================================
--- branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/ReadType.java 2012-03-08 14:14:21 UTC (rev 38617)
+++ branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/ReadType.java 2012-03-08 14:14:48 UTC (rev 38618)
@@ -143,6 +143,7 @@
// check input stream
final ImageInputStream inStream=(ImageInputStream) reader.getInput();
// read data
+ inStream.seek(0);
final RenderedOp raster = ImageReadDescriptor.create(
inStream,
imageIndex,
Modified: branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/Utils.java
===================================================================
--- branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/Utils.java 2012-03-08 14:14:21 UTC (rev 38617)
+++ branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/Utils.java 2012-03-08 14:14:48 UTC (rev 38618)
@@ -18,7 +18,9 @@
import java.awt.Color;
import java.awt.Rectangle;
+import java.awt.Shape;
import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
@@ -805,16 +807,12 @@
* in case the {@link ImageReader} or the
* {@link ImageInputStream} fail.
*/
- static Rectangle getDimension(final int imageIndex,
- final ImageInputStream inStream, final ImageReader reader)
+ static Rectangle getDimension(final int imageIndex,final ImageReader reader)
throws IOException {
- Utilities.ensureNonNull("inStream", inStream);
Utilities.ensureNonNull("reader", reader);
if (imageIndex < 0)
throw new IllegalArgumentException(Errors.format(
ErrorKeys.INDEX_OUT_OF_BOUNDS_$1, imageIndex));
- inStream.reset();
- reader.setInput(inStream);
return new Rectangle(0, 0, reader.getWidth(imageIndex), reader
.getHeight(imageIndex));
}
@@ -1561,4 +1559,89 @@
return true;
return false;
}
+
+ /**
+ * Checks if the Shape equates to a Rectangle, if it does it performs a conversion, otherwise
+ * returns null
+ * @param shape
+ * @return
+ */
+ static Rectangle toRectangle(Shape shape) {
+ if(shape instanceof Rectangle) {
+ return (Rectangle) shape;
+ }
+
+ if(shape == null) {
+ return null;
+ }
+
+ // check if it's equivalent to a rectangle
+ PathIterator iter = shape.getPathIterator(new AffineTransform());
+ double[] coords = new double[2];
+
+ // not enough points?
+ if(iter.isDone()) {
+ return null;
+ }
+
+ // get the first and init the data structures
+ iter.next();
+ int action = iter.currentSegment(coords);
+ if(action != PathIterator.SEG_MOVETO && action != PathIterator.SEG_LINETO) {
+ return null;
+ }
+ double minx = coords[0];
+ double miny = coords[1];
+ double maxx = minx;
+ double maxy = miny;
+ double prevx = minx;
+ double prevy = miny;
+ int i = 0;
+
+ // at most 4 steps, if more it's not a strict rectangle
+ for (; i < 4 && !iter.isDone(); i++) {
+ iter.next();
+ action = iter.currentSegment(coords);
+
+ if(action == PathIterator.SEG_CLOSE) {
+ break;
+ }
+ if(action != PathIterator.SEG_LINETO) {
+ return null;
+ }
+
+ // check orthogonal step (x does not change and y does, or vice versa)
+ double x = coords[0];
+ double y = coords[1];
+ if(!(prevx == x && prevy != y) &&
+ !(prevx != x && prevy == y)) {
+ return null;
+ }
+
+ // update mins and maxes
+ if(x < minx) {
+ minx = x;
+ } else if(x > maxx) {
+ maxx = x;
+ }
+ if(y < miny) {
+ miny = y;
+ } else if(y > maxy) {
+ maxy = y;
+ }
+
+ // keep track of prev step
+ prevx = x;
+ prevy = y;
+ }
+
+ // if more than 4 other points it's not a standard rectangle
+ iter.next();
+ if(!iter.isDone() || i != 3) {
+ return null;
+ }
+
+ // turn it into a rectangle
+ return new Rectangle2D.Double(minx, miny, maxx - minx, maxy - miny).getBounds();
+ }
}
Modified: branches/2.7.x/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/ImageMosaicReaderTest.java
===================================================================
--- branches/2.7.x/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/ImageMosaicReaderTest.java 2012-03-08 14:14:21 UTC (rev 38617)
+++ branches/2.7.x/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/ImageMosaicReaderTest.java 2012-03-08 14:14:48 UTC (rev 38618)
@@ -19,6 +19,8 @@
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileNotFoundException;
@@ -34,7 +36,9 @@
import java.util.TimeZone;
import java.util.logging.Logger;
+import javax.imageio.ImageIO;
import javax.media.jai.PlanarImage;
+import javax.media.jai.iterator.RectIterFactory;
import javax.media.jai.widget.ScrollingImagePanel;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
@@ -52,6 +56,7 @@
import org.geotools.coverage.grid.io.OverviewPolicy;
import org.geotools.coverage.grid.io.UnknownFormat;
import org.geotools.factory.Hints;
+import org.geotools.geometry.Envelope2D;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.parameter.Parameter;
import org.geotools.referencing.CRS;
@@ -61,8 +66,8 @@
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
+import org.opengis.geometry.Envelope;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.parameter.GeneralParameterValue;
import org.opengis.parameter.ParameterValue;
@@ -868,7 +873,80 @@
checkCoverage(reader, new GeneralParameterValue[] { gg, outTransp },title);
}
+
+ @Test
+ public void testRequestInHole() throws Exception {
+ final AbstractGridFormat format = getFormat(rgbAURL);
+ final ImageMosaicReader reader = getReader(rgbAURL, format);
+ assertNotNull(reader);
+
+ // ask to extract an area that is inside the coverage bbox, but in a hole (no data)
+ final ParameterValue<GridGeometry2D> ggp = AbstractGridFormat.READ_GRIDGEOMETRY2D.createValue();
+ Envelope2D env = new Envelope2D(reader.getCrs(), 500000, 3200000, 1000, 1000);
+ GridGeometry2D gg = new GridGeometry2D(new GridEnvelope2D(0, 0, 100, 100), (Envelope) env);
+ ggp.setValue(gg);
+
+ // red background
+ final ParameterValue<double[]> bgp = ImageMosaicFormat.BACKGROUND_VALUES.createValue();
+ bgp.setValue(new double[] {255, 0, 0, 255});
+
+ // read and check we actually got a coverage in the requested area
+ GridCoverage2D coverage = reader.read(new GeneralParameterValue[] {ggp, bgp});
+ assertNotNull(coverage);
+ assertTrue(coverage.getEnvelope2D().intersects(env));
+
+ // and that the color is the expected one given the background values provided
+ RenderedImage ri = coverage.getRenderedImage();
+ int[] pixel = new int[4];
+ Raster tile = ri.getTile(ri.getMinTileX() + 1, ri.getMinTileY() + 1);
+ tile.getPixel(tile.getMinX(), tile.getMinY(), pixel);
+ assertEquals(255, pixel[0]);
+ assertEquals(0, pixel[1]);
+ assertEquals(0, pixel[2]);
+ assertEquals(255, pixel[3]);
+ }
+
+ @Test
+ public void testRequestInOut() throws Exception {
+ final AbstractGridFormat format = getFormat(rgbAURL);
+ final ImageMosaicReader reader = getReader(rgbAURL, format);
+
+ assertNotNull(reader);
+
+ // ask to extract an area that is inside the coverage bbox, so that the area is partly
+ // inside the raster, and partly outside
+ final ParameterValue<GridGeometry2D> ggp = AbstractGridFormat.READ_GRIDGEOMETRY2D.createValue();
+ Envelope2D env = new Envelope2D(reader.getCrs(), 64887, 2499342, 646897 - 64887 , 3155705 - 2499342);
+ GridGeometry2D gg = new GridGeometry2D(new GridEnvelope2D(0, 0, 100, 100), (Envelope) env);
+ ggp.setValue(gg);
+
+ // red background
+ final ParameterValue<double[]> bgp = ImageMosaicFormat.BACKGROUND_VALUES.createValue();
+ bgp.setValue(new double[] {255, 0, 0, 255});
+
+ // read and check we actually got a coverage in the requested area
+ GridCoverage2D coverage = reader.read(new GeneralParameterValue[] {ggp, bgp});
+ assertNotNull(coverage);
+ System.out.println(coverage.getEnvelope2D());
+ System.out.println(env);
+ assertTrue(coverage.getEnvelope2D().contains(env));
+
+ // and that the color is the expected one given the background values provided
+ RenderedImage ri = coverage.getRenderedImage();
+ ImageIO.write(ri, "PNG", new File("/tmp/mix.png"));
+ System.out.println(ri.getNumXTiles());
+ System.out.println(ri.getNumYTiles());
+ int[] pixel = new int[4];
+ Raster tile = ri.getTile(ri.getMinTileX() + ri.getNumXTiles() - 1,
+ ri.getMinTileY() + ri.getNumYTiles() - 1);
+ tile.getPixel(tile.getWidth() / 2, tile.getHeight() / 2, pixel);
+ assertEquals(255, pixel[0]);
+ assertEquals(0, pixel[1]);
+ assertEquals(0, pixel[2]);
+ assertEquals(255, pixel[3]);
+ }
+
/**
* @param args
*/
|
|
From: <svn...@os...> - 2012-03-08 14:14:30
|
Author: aaime
Date: 2012-03-08 06:14:21 -0800 (Thu, 08 Mar 2012)
New Revision: 38617
Modified:
branches/2.7.x/modules/library/coverage/src/main/java/org/geotools/image/palette/CustomPaletteBuilder.java
branches/2.7.x/modules/library/coverage/src/test/java/org/geotools/image/palette/CustomPaletteBuilderTest.java
Log:
[GEOT-4065] CustomPaletteBuilder may fail on images with shifted tile origin
Modified: branches/2.7.x/modules/library/coverage/src/main/java/org/geotools/image/palette/CustomPaletteBuilder.java
===================================================================
--- branches/2.7.x/modules/library/coverage/src/main/java/org/geotools/image/palette/CustomPaletteBuilder.java 2012-03-08 14:13:58 UTC (rev 38616)
+++ branches/2.7.x/modules/library/coverage/src/main/java/org/geotools/image/palette/CustomPaletteBuilder.java 2012-03-08 14:14:21 UTC (rev 38617)
@@ -173,12 +173,18 @@
int minx = r.getMinX();
int miny = r.getMinY();
+ int sampleModelTx = r.getSampleModelTranslateX();
+ int sampleModelTy = r.getSampleModelTranslateY();
+
minx = minx < minx_ ? minx_ : minx;
miny = miny < miny_ ? miny_ : miny;
int maxx = minx + tileW;
int maxy = miny + tileH;
- maxx = maxx > maxx_ ? maxx_ : maxx;
- maxy = maxy > maxy_ ? maxy_ : maxy;
+ int maxxR = maxx + sampleModelTx;
+ int maxyR = maxy + sampleModelTy;
+ maxx = maxx > maxx_ ? (maxx_ > maxxR ? maxxR : maxx_) : (maxx > maxxR ? maxxR : maxx);
+ maxy = maxy > maxy_ ? (maxy_ > maxyR ? maxyR : maxy_) : (maxy > maxyR ? maxyR : maxy);
+
actualWidth = maxx - minx;
actualHeight = maxy - miny;
for (int j = miny, jj = dstTempY; j < maxy; j++, jj++) {
@@ -316,12 +322,17 @@
int minx = r.getMinX();
int miny = r.getMinY();
+ int sampleModelTx = r.getSampleModelTranslateX();
+ int sampleModelTy = r.getSampleModelTranslateY();
minx = minx < minx_ ? minx_ : minx;
miny = miny < miny_ ? miny_ : miny;
int maxx = minx + tileW;
int maxy = miny + tileH;
- maxx = maxx > maxx_ ? maxx_ : maxx;
- maxy = maxy > maxy_ ? maxy_ : maxy;
+ int maxxR = maxx + sampleModelTx;
+ int maxyR = maxy + sampleModelTy;
+ maxx = maxx > maxx_ ? (maxx_ > maxxR ? maxxR : maxx_) : (maxx > maxxR ? maxxR : maxx);
+ maxy = maxy > maxy_ ? (maxy_ > maxyR ? maxyR : maxy_) : (maxy > maxyR ? maxyR : maxy);
+
for (int j = miny; j < maxy; j++) {
if ((subsampley > 1) && ((j % subsampley) != 0)) {
continue;
Modified: branches/2.7.x/modules/library/coverage/src/test/java/org/geotools/image/palette/CustomPaletteBuilderTest.java
===================================================================
--- branches/2.7.x/modules/library/coverage/src/test/java/org/geotools/image/palette/CustomPaletteBuilderTest.java 2012-03-08 14:13:58 UTC (rev 38616)
+++ branches/2.7.x/modules/library/coverage/src/test/java/org/geotools/image/palette/CustomPaletteBuilderTest.java 2012-03-08 14:14:21 UTC (rev 38617)
@@ -19,20 +19,25 @@
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.RenderedImage;
+import java.awt.image.SampleModel;
import javax.media.jai.ImageLayout;
import javax.media.jai.JAI;
import javax.media.jai.OperationDescriptor;
import javax.media.jai.ParameterBlockJAI;
import javax.media.jai.PlanarImage;
+import javax.media.jai.TiledImage;
import junit.framework.TestCase;
import org.geotools.image.ImageWorker;
import org.junit.Test;
+import com.sun.media.jai.codecimpl.util.RasterFactory;
+
/**
* Testing custom code for color reduction.
*
@@ -97,6 +102,26 @@
}
+ @Test
+ public void testTranslatedImage() {
+ BufferedImage bi = new BufferedImage(256, 256, BufferedImage.TYPE_BYTE_GRAY);
+ TiledImage image = new TiledImage(0, 0, 256, 256, 1, 1, bi.getSampleModel().createCompatibleSampleModel(256, 256), bi.getColorModel());
+ Graphics g = image.createGraphics();
+ g.setColor(Color.WHITE);
+ g.fillRect(0, 0, 20, 20);
+ g.setColor(new Color(20, 20, 20)); // A dark gray
+ g.fillRect(20, 20, 20, 20);
+ g.setColor(new Color(200, 200, 200)); // A light gray
+ g.fillRect(0, 20, 20, 20);
+ g.dispose();
+ CustomPaletteBuilder builder = new CustomPaletteBuilder(image, 256, 1, 1, 1);
+ RenderedImage indexed = builder.buildPalette().getIndexedImage();
+ assertTrue(indexed.getColorModel() instanceof IndexColorModel);
+ IndexColorModel icm = (IndexColorModel) indexed.getColorModel();
+ assertEquals(4, icm.getMapSize()); //Black background, white fill, light gray fill, dark gray fill = 4 colors
+
+ }
+
@Test
public void testFourColor() {
|
|
From: <svn...@os...> - 2012-03-08 14:14:06
|
Author: aaime
Date: 2012-03-08 06:13:58 -0800 (Thu, 08 Mar 2012)
New Revision: 38616
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-4064] ImageWorker.affine misbehaves in case of chained, inverted transforms
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-03-08 10:17:06 UTC (rev 38615)
+++ branches/2.7.x/modules/library/coverage/src/main/java/org/geotools/image/ImageWorker.java 2012-03-08 14:13:58 UTC (rev 38616)
@@ -2863,6 +2863,7 @@
// did it become a identity after the combination?
if(!hasScaleX && !hasScaleY && !hasShearX && !hasShearY && !hasTranslateX && !hasTranslateY) {
+ this.image = source;
return this;
}
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-03-08 10:17:06 UTC (rev 38615)
+++ branches/2.7.x/modules/library/coverage/src/test/java/org/geotools/image/ImageWorkerTest.java 2012-03-08 14:13:58 UTC (rev 38616)
@@ -26,6 +26,7 @@
import java.awt.Color;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
@@ -804,4 +805,26 @@
assertEquals(Math.round(inputCM.getAlpha(i) * 0.5), outputCM.getAlpha(i));
}
}
+
+ @Test
+ public void testOptimizeAffine() throws Exception {
+ BufferedImage bi = new BufferedImage(100, 100, BufferedImage.TYPE_3BYTE_BGR);
+ ImageWorker iw = new ImageWorker(bi);
+
+ // apply straight translation
+ AffineTransform at = AffineTransform.getTranslateInstance(100, 100);
+ iw.affine(at, null, null);
+ RenderedImage t1 = iw.getRenderedImage();
+ assertEquals(100, t1.getMinX());
+ assertEquals(100, t1.getMinY());
+
+ // now go back
+ AffineTransform atInverse = AffineTransform.getTranslateInstance(-100, -100);
+ iw.affine(atInverse, null, null);
+ RenderedImage t2 = iw.getRenderedImage();
+ assertEquals(0, t2.getMinX());
+ assertEquals(0, t2.getMinY());
+ assertSame(bi, t2);
+
+ }
}
|
|
From: <svn...@os...> - 2012-03-08 10:17:15
|
Author: mbedward
Date: 2012-03-08 02:17:06 -0800 (Thu, 08 Mar 2012)
New Revision: 38615
Added:
trunk/modules/unsupported/swing/src/test/java/org/geotools/swing/tool/InfoToolHelperLookupTest.java
Modified:
trunk/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/InfoToolHelperLookup.java
Log:
GEOT-4062: Using ServiceLoader in InfoToolHelperLookup. Added tests.
Modified: trunk/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/InfoToolHelperLookup.java
===================================================================
--- trunk/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/InfoToolHelperLookup.java 2012-03-07 10:48:07 UTC (rev 38614)
+++ trunk/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/InfoToolHelperLookup.java 2012-03-08 10:17:06 UTC (rev 38615)
@@ -17,14 +17,10 @@
package org.geotools.swing.tool;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.ref.WeakReference;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
-import java.util.logging.Level;
+import java.util.ServiceLoader;
import java.util.logging.Logger;
import org.geotools.map.Layer;
@@ -40,19 +36,17 @@
class InfoToolHelperLookup {
private static final Logger LOGGER = Logger.getLogger("org.geotools.swing");
- private static final String SPI_NAME =
- "META-INF/services/org.geotools.swing.tool.InfoToolHelper";
-
- private static WeakReference<List<Class>> cache;
+ private static List<InfoToolHelper> cachedInstances;
public static InfoToolHelper getHelper(Layer layer) {
- List<Class> helperClasses = InfoToolHelperLookup.getProviders();
- for (Class c : helperClasses) {
+ loadProviders();
+
+ for (InfoToolHelper helper : cachedInstances) {
try {
- InfoToolHelper helper = (InfoToolHelper) c.newInstance();
if (helper.isSupportedLayer(layer)) {
- return helper;
+ return helper.getClass().newInstance();
}
+
} catch (Exception ex) {
throw new RuntimeException(ex);
}
@@ -62,78 +56,22 @@
}
/**
- * Gets classes that implement the InfoToolHelper SPI.
- *
- * @return list of implementing classes
+ * Caches available classes which implement the InfoToolHelper SPI.
*/
- private static List<Class> getProviders() {
+ private static void loadProviders() {
List<Class> providers = null;
- if (cache != null) {
- providers = cache.get();
- }
-
- if (providers == null) {
- providers = getProvidersFromSpiFile();
- cache = new WeakReference<List<Class>>(providers);
- }
-
- return providers;
- }
-
- /**
- * Read class names from a registry file and return the list of
- * implementing classes.
- *
- * @param SPI_NAME a fully qualified interface name
- *
- * @return list of implementing classes
- */
- private static List<Class> getProvidersFromSpiFile() {
- List<Class> providers = new ArrayList<Class>();
-
- ClassLoader cl = InfoToolHelperLookup.class.getClassLoader();
- if (cl != null) {
- InputStream str = cl.getResourceAsStream(SPI_NAME);
- if (str != null) {
- BufferedReader reader = new BufferedReader(new InputStreamReader(str));
- String line = null;
-
- try {
- while ((line = reader.readLine()) != null) {
- String text = line.trim();
- if (text.length() > 0 && !text.startsWith("#")) {
- try {
- providers.add(Class.forName(text));
- } catch (ClassNotFoundException ex) {
- LOGGER.log(Level.WARNING, "Class not found: {0}", text);
- }
- }
- }
- } catch (IOException ex) {
- LOGGER.log(Level.SEVERE, "Problem reading services file: {0}", SPI_NAME);
-
- } finally {
- try {
- str.close();
- } catch (Throwable e) {
- // ignore
- }
-
- try {
- if (reader != null) {
- reader.close();
- }
- } catch (Throwable e) {
- // ignore
- }
- }
-
- } else {
- LOGGER.log(Level.SEVERE, "Could not find {0}", SPI_NAME);
+ if (cachedInstances == null) {
+ cachedInstances = new ArrayList<InfoToolHelper>();
+
+ ServiceLoader<InfoToolHelper> loader =
+ ServiceLoader.load(InfoToolHelper.class);
+
+ Iterator<InfoToolHelper> iter = loader.iterator();
+ while (iter.hasNext()) {
+ cachedInstances.add(iter.next());
}
}
-
- return providers;
}
+
}
Added: trunk/modules/unsupported/swing/src/test/java/org/geotools/swing/tool/InfoToolHelperLookupTest.java
===================================================================
--- trunk/modules/unsupported/swing/src/test/java/org/geotools/swing/tool/InfoToolHelperLookupTest.java (rev 0)
+++ trunk/modules/unsupported/swing/src/test/java/org/geotools/swing/tool/InfoToolHelperLookupTest.java 2012-03-08 10:17:06 UTC (rev 38615)
@@ -0,0 +1,65 @@
+/*
+ * GeoTools - The Open Source Java GIS Toolkit
+ * http://geotools.org
+ *
+ * (C) 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.swing.tool;
+
+import org.geotools.coverage.CoverageFactoryFinder;
+import org.geotools.coverage.grid.GridCoverage2D;
+import org.geotools.coverage.grid.GridCoverageFactory;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.map.GridCoverageLayer;
+import org.geotools.map.Layer;
+import org.geotools.swing.testutils.TestDataUtils;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+/**
+ * Tests for the info tool helper lookup.
+ *
+ * @author Michael Bedward
+ * @since 8.0
+ * @source $URL: $
+ * @version $Id: $
+ */
+public class InfoToolHelperLookupTest {
+
+ @Test
+ public void featureLayerHelper() throws Exception {
+ Layer layer = TestDataUtils.getPolygonLayer();
+ InfoToolHelper helper = InfoToolHelperLookup.getHelper(layer);
+ assertNotNull(helper);
+ assertEquals(FeatureLayerHelper.class, helper.getClass());
+ }
+
+ @Test
+ public void gridCoverageLayerHelper() throws Exception {
+ float[][] data = {
+ {1, 2, 3, 4},
+ {5, 6, 7, 8}
+ };
+
+ ReferencedEnvelope env = new ReferencedEnvelope(0, 4, 0, 2, null);
+ GridCoverageFactory gcf = CoverageFactoryFinder.getGridCoverageFactory(null);
+ GridCoverage2D cov = gcf.create("coverage", data, env);
+ Layer layer = new GridCoverageLayer(cov, null);
+
+ InfoToolHelper helper = InfoToolHelperLookup.getHelper(layer);
+ assertNotNull(helper);
+ assertEquals(GridCoverageLayerHelper.class, helper.getClass());
+ }
+}
|
|
From: <svn...@os...> - 2012-03-07 10:48:14
|
Author: aaime Date: 2012-03-07 02:48:07 -0800 (Wed, 07 Mar 2012) New Revision: 38614 Added: trunk/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/coverageCenter.sld Log: Forgot to add a style Added: trunk/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/coverageCenter.sld =================================================================== --- trunk/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/coverageCenter.sld (rev 0) +++ trunk/modules/library/render/src/test/resources/org/geotools/renderer/lite/test-data/coverageCenter.sld 2012-03-07 10:48:07 UTC (rev 38614) @@ -0,0 +1,38 @@ +<?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> + <Name>default_line</Name> + <UserStyle> + <!-- Styles can have names, titles and abstracts --> + <Title>Default Line</Title> + <Abstract>A sample style that draws a line</Abstract> + <!-- FeatureTypeStyles describe how to render different features --> + <!-- A FeatureTypeStyle for rendering lines --> + <FeatureTypeStyle> + <Transformation> + <ogc:Function name="CoverageCenter"> + </ogc:Function> + </Transformation> + + <Rule> + <PointSymbolizer> + <Graphic> + <Mark> + <WellKnownName>circle</WellKnownName> + <Fill> + <CssParameter name="fill">0xFF0000 + </CssParameter> + </Fill> + </Mark> + <Size>32</Size> + </Graphic> + </PointSymbolizer> + </Rule> + </FeatureTypeStyle> + </UserStyle> + </NamedLayer> +</StyledLayerDescriptor> \ No newline at end of file |
Author: aaime
Date: 2012-03-07 02:29:08 -0800 (Wed, 07 Mar 2012)
New Revision: 38613
Added:
trunk/modules/library/render/src/test/java/org/geotools/renderer/lite/CoverageCenterFunction.java
trunk/modules/library/render/src/test/java/org/geotools/renderer/lite/RenderingTransformationTest.java
trunk/modules/library/render/src/test/resources/META-INF/
trunk/modules/library/render/src/test/resources/META-INF/services/
trunk/modules/library/render/src/test/resources/META-INF/services/org.opengis.filter.expression.Function
Modified:
trunk/modules/library/render/pom.xml
trunk/modules/library/render/src/main/java/org/geotools/renderer/lite/StreamingRenderer.java
Log:
[GEOT-4059] Coverage based rendering transformation will likely fail if map is reprojected
Modified: trunk/modules/library/render/pom.xml
===================================================================
--- trunk/modules/library/render/pom.xml 2012-03-06 06:10:23 UTC (rev 38612)
+++ trunk/modules/library/render/pom.xml 2012-03-07 10:29:08 UTC (rev 38613)
@@ -150,6 +150,12 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.geotools</groupId>
+ <artifactId>gt-geotiff</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
Modified: trunk/modules/library/render/src/main/java/org/geotools/renderer/lite/StreamingRenderer.java
===================================================================
--- trunk/modules/library/render/src/main/java/org/geotools/renderer/lite/StreamingRenderer.java 2012-03-06 06:10:23 UTC (rev 38612)
+++ trunk/modules/library/render/src/main/java/org/geotools/renderer/lite/StreamingRenderer.java 2012-03-07 10:29:08 UTC (rev 38613)
@@ -2014,6 +2014,10 @@
* @param attributeNames
*/
void checkAttributeExistence(FeatureType schema, Query query) {
+ if(query.getProperties() == null) {
+ return;
+ }
+
for (PropertyName attribute : query.getProperties()) {
if(attribute.evaluate(schema) == null) {
if (schema instanceof SimpleFeatureType) {
@@ -2034,7 +2038,7 @@
}
FeatureCollection applyRenderingTransformation(Expression transformation,
- FeatureSource featureSource, Query query, GridGeometry2D gridGeometry) throws IOException, SchemaException, TransformException {
+ FeatureSource featureSource, Query query, GridGeometry2D gridGeometry) throws IOException, SchemaException, TransformException, FactoryException {
Object result = null;
// check if it's a wrapper coverage or a wrapped reader
@@ -2043,12 +2047,10 @@
if(schema instanceof SimpleFeatureType) {
SimpleFeatureType simpleSchema = (SimpleFeatureType) schema;
GridCoverage2D coverage = null;
- if(FeatureUtilities.isWrappedCoverage(simpleSchema)) {
+ if(FeatureUtilities.isWrappedCoverage(simpleSchema) || FeatureUtilities.isWrappedCoverageReader(simpleSchema)) {
isRasterData = true;
- throw new UnsupportedOperationException("Don't have support for plain coverages " +
- "in rendering transformations now");
- } else if(FeatureUtilities.isWrappedCoverageReader(simpleSchema)) {
- isRasterData = true;
+
+ // get the desired grid geometry
GridGeometry2D readGG = gridGeometry;
if(transformation instanceof RenderingTransformation) {
RenderingTransformation tx = (RenderingTransformation) transformation;
@@ -2056,45 +2058,52 @@
// TODO: override the read params and force this grid geometry, or something
// similar to this (like passing it as a param to readCoverage
}
+
Feature gridWrapper = featureSource.getFeatures().features().next();
- final Object params = paramsPropertyName.evaluate(gridWrapper);
- final AbstractGridCoverage2DReader reader = (AbstractGridCoverage2DReader) gridPropertyName.evaluate(gridWrapper);
- // don't read more than the native resolution (in case we are oversampling)
- if(CRS.equalsIgnoreMetadata(reader.getCrs(), gridGeometry.getCoordinateReferenceSystem())) {
- MathTransform g2w = reader.getOriginalGridToWorld(PixelInCell.CELL_CENTER);
- if(g2w instanceof AffineTransform2D && readGG.getGridToCRS2D() instanceof AffineTransform2D) {
- AffineTransform2D atOriginal = (AffineTransform2D) g2w;
- AffineTransform2D atMap = (AffineTransform2D) readGG.getGridToCRS2D();
- if(XAffineTransform.getScale(atMap) < XAffineTransform.getScale(atOriginal)) {
- // we need to go trough some convoluted code to make sure the new grid geometry
- // has at least one pixel
-
- org.opengis.geometry.Envelope worldEnvelope = gridGeometry.getEnvelope();
- GeneralEnvelope transformed = org.geotools.referencing.CRS.transform(atOriginal.inverse(), worldEnvelope);
- int minx = (int) Math.floor(transformed.getMinimum(0));
- int miny = (int) Math.floor(transformed.getMinimum(1));
- int maxx = (int) Math.ceil(transformed.getMaximum(0));
- int maxy = (int) Math.ceil(transformed.getMaximum(1));
- Rectangle rect = new Rectangle(minx, miny, (maxx - minx), (maxy - miny));
- GridEnvelope2D gridEnvelope = new GridEnvelope2D(rect);
- readGG = new GridGeometry2D(gridEnvelope, atOriginal, worldEnvelope.getCoordinateReferenceSystem());
-
- // readGG = new GridGeometry2D(PixelInCell.CELL_CORNER, );
+ if(FeatureUtilities.isWrappedCoverageReader(simpleSchema)) {
+ final Object params = paramsPropertyName.evaluate(gridWrapper);
+ final AbstractGridCoverage2DReader reader = (AbstractGridCoverage2DReader) gridPropertyName.evaluate(gridWrapper);
+ // don't read more than the native resolution (in case we are oversampling)
+ if(CRS.equalsIgnoreMetadata(reader.getCrs(), gridGeometry.getCoordinateReferenceSystem())) {
+ MathTransform g2w = reader.getOriginalGridToWorld(PixelInCell.CELL_CENTER);
+ if(g2w instanceof AffineTransform2D && readGG.getGridToCRS2D() instanceof AffineTransform2D) {
+ AffineTransform2D atOriginal = (AffineTransform2D) g2w;
+ AffineTransform2D atMap = (AffineTransform2D) readGG.getGridToCRS2D();
+ if(XAffineTransform.getScale(atMap) < XAffineTransform.getScale(atOriginal)) {
+ // we need to go trough some convoluted code to make sure the new grid geometry
+ // has at least one pixel
+
+ org.opengis.geometry.Envelope worldEnvelope = gridGeometry.getEnvelope();
+ GeneralEnvelope transformed = org.geotools.referencing.CRS.transform(atOriginal.inverse(), worldEnvelope);
+ int minx = (int) Math.floor(transformed.getMinimum(0));
+ int miny = (int) Math.floor(transformed.getMinimum(1));
+ int maxx = (int) Math.ceil(transformed.getMaximum(0));
+ int maxy = (int) Math.ceil(transformed.getMaximum(1));
+ Rectangle rect = new Rectangle(minx, miny, (maxx - minx), (maxy - miny));
+ GridEnvelope2D gridEnvelope = new GridEnvelope2D(rect);
+ readGG = new GridGeometry2D(gridEnvelope, atOriginal, worldEnvelope.getCoordinateReferenceSystem());
+ }
}
- }
+ }
+ coverage = readCoverage(reader, params, readGG);
+ } else {
+ coverage = (GridCoverage2D) gridPropertyName.evaluate(gridWrapper);
}
- coverage = readCoverage(reader, params, readGG);
// readers will return null if there is no coverage in the area
if(coverage != null) {
if(readGG != null) {
// Crop will fail if we try to crop outside of the coverage area
- GeneralEnvelope cropEnvelope = new GeneralEnvelope(readGG.getEnvelope());
- if(coverage.getEnvelope2D().intersects(cropEnvelope.toRectangle2D())) {
+ ReferencedEnvelope renderingEnvelope = new ReferencedEnvelope(readGG.getEnvelope());
+ CoordinateReferenceSystem coverageCRS = coverage.getCoordinateReferenceSystem2D();
+ if(!CRS.equalsIgnoreMetadata(renderingEnvelope.getCoordinateReferenceSystem(), coverageCRS)) {
+ renderingEnvelope = renderingEnvelope.transform(coverageCRS, true);
+ }
+ if(coverage.getEnvelope2D().intersects(renderingEnvelope)) {
// the resulting coverage might be larger than the readGG envelope, shall we crop it?
final ParameterValueGroup param = CROP.getParameters();
param.parameter("Source").setValue(coverage);
- param.parameter("Envelope").setValue(cropEnvelope);
+ param.parameter("Envelope").setValue(renderingEnvelope);
coverage = (GridCoverage2D) PROCESSOR.doOperation(param);
} else {
coverage = null;
@@ -2158,7 +2167,7 @@
// transform them
result = transformation.evaluate(originalFeatures);
- }
+ }
// null safety, a transformation might be free to return null
if(result == null) {
@@ -2227,6 +2236,13 @@
Filter original = query.getFilter();
Filter renamedFilter = (Filter) original.accept(visitor, null);
result.setFilter(renamedFilter);
+ } else if(originalSchema instanceof SimpleFeatureType
+ && (FeatureUtilities.isWrappedCoverage((SimpleFeatureType) originalSchema)
+ || FeatureUtilities.isWrappedCoverageReader((SimpleFeatureType) originalSchema))) {
+ // use all the properties generated by the transformation, the query normally in this
+ // case contains grid/params/geom or grid/geom which have nothing to do with
+ // the actual attributes we are going to use, especially in raster to vector transformations
+ result.setFilter(query.getFilter());
} else {
result.setPropertyNames(query.getPropertyNames());
result.setFilter(query.getFilter());
Added: trunk/modules/library/render/src/test/java/org/geotools/renderer/lite/CoverageCenterFunction.java
===================================================================
--- trunk/modules/library/render/src/test/java/org/geotools/renderer/lite/CoverageCenterFunction.java (rev 0)
+++ trunk/modules/library/render/src/test/java/org/geotools/renderer/lite/CoverageCenterFunction.java 2012-03-07 10:29:08 UTC (rev 38613)
@@ -0,0 +1,52 @@
+package org.geotools.renderer.lite;
+
+import static org.geotools.filter.capability.FunctionNameImpl.*;
+
+import org.geotools.coverage.grid.GridCoverage2D;
+import org.geotools.data.DataUtilities;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
+import org.geotools.filter.FunctionExpressionImpl;
+import org.geotools.filter.capability.FunctionNameImpl;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.capability.FunctionName;
+import org.opengis.geometry.Envelope;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.Point;
+
+/**
+ * A test rendering transformation that returns the center of the provided coverage
+ *
+ * @author Andrea Aime - GeoSolutions
+ */
+public class CoverageCenterFunction extends FunctionExpressionImpl {
+
+ public static FunctionName NAME = new FunctionNameImpl("CoverageCenter", parameter("coverage",
+ GridCoverage2D.class));
+
+ public CoverageCenterFunction() {
+ super(NAME);
+ }
+
+ public Object evaluate(Object gc) {
+ GridCoverage2D coverage = (GridCoverage2D) gc;
+
+ Envelope env = coverage.getEnvelope();
+ GeometryFactory gf = new GeometryFactory();
+ Point center = gf.createPoint(new Coordinate(env.getMedian(0), env.getMedian(1)));
+
+ SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
+ tb.setName("center");
+ tb.add("geom", Point.class, coverage.getCoordinateReferenceSystem2D());
+ SimpleFeatureType ft = tb.buildFeatureType();
+
+ SimpleFeatureBuilder fb = new SimpleFeatureBuilder(ft);
+ fb.add(center);
+ SimpleFeature f = fb.buildFeature(null);
+
+ return DataUtilities.collection(f);
+ }
+}
Added: trunk/modules/library/render/src/test/java/org/geotools/renderer/lite/RenderingTransformationTest.java
===================================================================
--- trunk/modules/library/render/src/test/java/org/geotools/renderer/lite/RenderingTransformationTest.java (rev 0)
+++ trunk/modules/library/render/src/test/java/org/geotools/renderer/lite/RenderingTransformationTest.java 2012-03-07 10:29:08 UTC (rev 38613)
@@ -0,0 +1,100 @@
+package org.geotools.renderer.lite;
+
+import static org.junit.Assert.*;
+
+import java.awt.Color;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+
+import org.geotools.gce.geotiff.GeoTiffReader;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.map.GridCoverageLayer;
+import org.geotools.map.GridReaderLayer;
+import org.geotools.map.MapContent;
+import org.geotools.referencing.CRS;
+import org.geotools.styling.Style;
+import org.geotools.TestData;
+import org.junit.Before;
+import org.junit.Test;
+
+public class RenderingTransformationTest {
+
+ private static final long TIME = 4000;
+
+ @Before
+ public void setup() {
+ // System.setProperty("org.geotools.test.interactive", "true");
+ }
+
+ @Test
+ public void testTransformReprojectedGridReader() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "coverageCenter.sld");
+
+ GeoTiffReader reader = new GeoTiffReader(TestData.copy(this, "geotiff/world.tiff"));
+
+ MapContent mc = new MapContent();
+ mc.addLayer(new GridReaderLayer(reader, style));
+
+ StreamingRenderer renderer = new StreamingRenderer();
+ renderer.setMapContent(mc);
+
+ ReferencedEnvelope reWgs84 = new ReferencedEnvelope(-70, 70, -160, 160, CRS.decode("EPSG:4326"));
+ ReferencedEnvelope re = reWgs84.transform(CRS.decode("EPSG:3857"), true);
+
+ BufferedImage image = RendererBaseTest.showRender("Lines with circle stroke", renderer,
+ TIME, re);
+ // if everything worked we are going to have a red dot in the middle of the map
+ assertEquals(Color.RED, getPixelColor(image, image.getWidth() / 2, image.getHeight() / 2));
+ assertEquals(Color.WHITE, getPixelColor(image, image.getWidth() / 4, image.getHeight() / 2));
+ assertEquals(Color.WHITE, getPixelColor(image, image.getWidth() / 2, image.getHeight() / 4));
+ assertEquals(Color.WHITE, getPixelColor(image, image.getWidth() / 4, image.getHeight() / 4));
+ }
+
+ @Test
+ public void testTransformReprojectedGridCoverage() throws Exception {
+ Style style = RendererBaseTest.loadStyle(this, "coverageCenter.sld");
+
+ GeoTiffReader reader = new GeoTiffReader(TestData.copy(this, "geotiff/world.tiff"));
+
+ MapContent mc = new MapContent();
+ mc.addLayer(new GridCoverageLayer(reader.read(null), style));
+
+ StreamingRenderer renderer = new StreamingRenderer();
+ renderer.setMapContent(mc);
+
+ ReferencedEnvelope reWgs84 = new ReferencedEnvelope(-70, 70, -160, 160, CRS.decode("EPSG:4326"));
+ ReferencedEnvelope re = reWgs84.transform(CRS.decode("EPSG:3857"), true);
+
+ BufferedImage image = RendererBaseTest.showRender("Lines with circle stroke", renderer,
+ TIME, re);
+ // if everything worked we are going to have a red dot in the middle of the map
+ assertEquals(Color.RED, getPixelColor(image, image.getWidth() / 2, image.getHeight() / 2));
+ assertEquals(Color.WHITE, getPixelColor(image, image.getWidth() / 4, image.getHeight() / 2));
+ assertEquals(Color.WHITE, getPixelColor(image, image.getWidth() / 2, image.getHeight() / 4));
+ assertEquals(Color.WHITE, getPixelColor(image, image.getWidth() / 4, image.getHeight() / 4));
+
+ }
+
+ /**
+ * Gets a specific pixel color from the specified buffered image
+ * @param image
+ * @param i
+ * @param j
+ * @param color
+ * @return
+ */
+ protected Color getPixelColor(BufferedImage image, int i, int j) {
+ ColorModel cm = image.getColorModel();
+ Raster raster = image.getRaster();
+ Object pixel = raster.getDataElements(i, j, null);
+
+ Color actual;
+ if(cm.hasAlpha()) {
+ actual = new Color(cm.getRed(pixel), cm.getGreen(pixel), cm.getBlue(pixel), cm.getAlpha(pixel));
+ } else {
+ actual = new Color(cm.getRed(pixel), cm.getGreen(pixel), cm.getBlue(pixel), 255);
+ }
+ return actual;
+ }
+}
Added: trunk/modules/library/render/src/test/resources/META-INF/services/org.opengis.filter.expression.Function
===================================================================
--- trunk/modules/library/render/src/test/resources/META-INF/services/org.opengis.filter.expression.Function (rev 0)
+++ trunk/modules/library/render/src/test/resources/META-INF/services/org.opengis.filter.expression.Function 2012-03-07 10:29:08 UTC (rev 38613)
@@ -0,0 +1 @@
+org.geotools.renderer.lite.CoverageCenterFunction
\ No newline at end of file
|
|
From: <svn...@os...> - 2012-03-06 06:10:29
|
Author: mbedward
Date: 2012-03-05 22:10:23 -0800 (Mon, 05 Mar 2012)
New Revision: 38612
Modified:
trunk/modules/unsupported/swing/src/main/java/org/geotools/swing/control/JCoordsStatusBarItem.java
Log:
GEOT-4058: constructor should be public
Modified: trunk/modules/unsupported/swing/src/main/java/org/geotools/swing/control/JCoordsStatusBarItem.java
===================================================================
--- trunk/modules/unsupported/swing/src/main/java/org/geotools/swing/control/JCoordsStatusBarItem.java 2012-03-06 01:32:05 UTC (rev 38611)
+++ trunk/modules/unsupported/swing/src/main/java/org/geotools/swing/control/JCoordsStatusBarItem.java 2012-03-06 06:10:23 UTC (rev 38612)
@@ -67,7 +67,7 @@
*
* @param mapPane the map pane
*/
- JCoordsStatusBarItem(MapPane mapPane) {
+ public JCoordsStatusBarItem(MapPane mapPane) {
super(COMPONENT_NAME);
if (mapPane == null) {
|
|
From: <svn...@os...> - 2012-03-06 01:32:11
|
Author: mbedward
Date: 2012-03-05 17:32:05 -0800 (Mon, 05 Mar 2012)
New Revision: 38611
Modified:
trunk/modules/unsupported/swing/src/main/java/org/geotools/swing/JMapPane.java
Log:
GEOT-4056: guard against the map pane setting map for renderer more than once
Modified: trunk/modules/unsupported/swing/src/main/java/org/geotools/swing/JMapPane.java
===================================================================
--- trunk/modules/unsupported/swing/src/main/java/org/geotools/swing/JMapPane.java 2012-03-04 23:06:35 UTC (rev 38610)
+++ trunk/modules/unsupported/swing/src/main/java/org/geotools/swing/JMapPane.java 2012-03-06 01:32:05 UTC (rev 38611)
@@ -85,7 +85,12 @@
public void setMapContent(MapContent content) {
super.setMapContent(content);
if (content != null && renderer != null) {
- renderer.setMapContent(mapContent);
+ // If the new map content had layers to draw, and this pane is visible,
+ // then the map content will already have been set with the renderer
+ //
+ if (renderer.getMapContent() != content) { // just check reference equality
+ renderer.setMapContent(mapContent);
+ }
}
}
|
|
From: <svn...@os...> - 2012-03-04 23:06:41
|
Author: simonegiannecchini
Date: 2012-03-04 15:06:35 -0800 (Sun, 04 Mar 2012)
New Revision: 38610
Modified:
branches/2.7.x/pom.xml
Log:
GEOT-4055
Modified: branches/2.7.x/pom.xml
===================================================================
--- branches/2.7.x/pom.xml 2012-03-04 23:03:34 UTC (rev 38609)
+++ branches/2.7.x/pom.xml 2012-03-04 23:06:35 UTC (rev 38610)
@@ -73,7 +73,7 @@
<stress.skip.pattern>**/*StressTest.java</stress.skip.pattern>
<test.maxHeapSize>512M</test.maxHeapSize>
<src.output>${basedir}/target</src.output>
- <imageio.ext.version>1.1.2</imageio.ext.version>
+ <imageio.ext.version>1.1.3</imageio.ext.version>
<jt.version>1.1.1</jt.version>
<jvm.opts></jvm.opts>
<maven.build.timestamp.format>dd-MMM-yyyy HH:mm</maven.build.timestamp.format>
@@ -1367,7 +1367,7 @@
<modules>
<module>build</module>
<module>modules</module>
- <module>docs</module>
+ <!--module>docs</module-->
<module>demo</module>
</modules>
</project>
|
|
From: <svn...@os...> - 2012-03-04 23:03:41
|
Author: simonegiannecchini
Date: 2012-03-04 15:03:34 -0800 (Sun, 04 Mar 2012)
New Revision: 38609
Modified:
trunk/pom.xml
Log:
GEOT-4055
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2012-03-04 13:37:51 UTC (rev 38608)
+++ trunk/pom.xml 2012-03-04 23:03:34 UTC (rev 38609)
@@ -91,7 +91,7 @@
<test.exclude.pattern>disabled</test.exclude.pattern>
<test.maxHeapSize>512M</test.maxHeapSize>
<src.output>${basedir}/target</src.output>
- <imageio.ext.version>1.1.2</imageio.ext.version>
+ <imageio.ext.version>1.1.3</imageio.ext.version>
<jt.version>1.2.0</jt.version>
<jvm.opts></jvm.opts>
<maven.build.timestamp.format>dd-MMM-yyyy HH:mm</maven.build.timestamp.format>
|
|
From: <svn...@os...> - 2012-03-04 13:37:58
|
Author: aaime
Date: 2012-03-04 05:37:51 -0800 (Sun, 04 Mar 2012)
New Revision: 38608
Added:
branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/ForcedCRSOperation.java
Log:
Adding missing class
Added: branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/ForcedCRSOperation.java
===================================================================
--- branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/ForcedCRSOperation.java (rev 0)
+++ branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/ForcedCRSOperation.java 2012-03-04 13:37:51 UTC (rev 38608)
@@ -0,0 +1,87 @@
+package org.geotools.referencing.operation;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.opengis.metadata.extent.Extent;
+import org.opengis.metadata.quality.PositionalAccuracy;
+import org.opengis.referencing.ReferenceIdentifier;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.util.GenericName;
+import org.opengis.util.InternationalString;
+
+/**
+ * Used by {@link AuthorityBackedFactory} when concanating operations, in case we're concatenating
+ * identities, but so that the source or target CRS are not the same as the non identity part. This
+ * happens, for example, when trying to work against a projected CRS with a wrapped geographic CRS
+ * axis in lon/lat order, and with the database providing an operation that uses the same projected
+ * CRS around a geographic CRS with axis in lat/lon order
+ *
+ * @author Andrea Aime - GeoSolutions
+ */
+class ForcedCRSOperation implements CoordinateOperation {
+
+ CoordinateOperation delegate;
+
+ CoordinateReferenceSystem sourceCRS;
+
+ CoordinateReferenceSystem targetCRS;
+
+ public ForcedCRSOperation(CoordinateOperation delegate, CoordinateReferenceSystem sourceCRS,
+ CoordinateReferenceSystem targetCRS) {
+ this.delegate = delegate;
+ this.sourceCRS = sourceCRS;
+ this.targetCRS = targetCRS;
+ }
+
+ public CoordinateReferenceSystem getSourceCRS() {
+ return sourceCRS;
+ }
+
+ public CoordinateReferenceSystem getTargetCRS() {
+ return targetCRS;
+ }
+
+ public ReferenceIdentifier getName() {
+ return delegate.getName();
+ }
+
+ public Collection<GenericName> getAlias() {
+ return delegate.getAlias();
+ }
+
+ public Set<ReferenceIdentifier> getIdentifiers() {
+ return delegate.getIdentifiers();
+ }
+
+ public InternationalString getRemarks() {
+ return delegate.getRemarks();
+ }
+
+ public String toWKT() throws UnsupportedOperationException {
+ return delegate.toWKT();
+ }
+
+ public String getOperationVersion() {
+ return delegate.getOperationVersion();
+ }
+
+ public Collection<PositionalAccuracy> getCoordinateOperationAccuracy() {
+ return delegate.getCoordinateOperationAccuracy();
+ }
+
+ public Extent getDomainOfValidity() {
+ return delegate.getDomainOfValidity();
+ }
+
+ public InternationalString getScope() {
+ return delegate.getScope();
+ }
+
+ public MathTransform getMathTransform() {
+ return delegate.getMathTransform();
+ }
+
+}
|
|
From: <svn...@os...> - 2012-03-04 13:35:19
|
Author: aaime
Date: 2012-03-04 05:35:11 -0800 (Sun, 04 Mar 2012)
New Revision: 38607
Added:
trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/ForcedCRSOperation.java
Log:
Adding missing class
Added: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/ForcedCRSOperation.java
===================================================================
--- trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/ForcedCRSOperation.java (rev 0)
+++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/ForcedCRSOperation.java 2012-03-04 13:35:11 UTC (rev 38607)
@@ -0,0 +1,87 @@
+package org.geotools.referencing.operation;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.opengis.metadata.extent.Extent;
+import org.opengis.metadata.quality.PositionalAccuracy;
+import org.opengis.referencing.ReferenceIdentifier;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.util.GenericName;
+import org.opengis.util.InternationalString;
+
+/**
+ * Used by {@link AuthorityBackedFactory} when concanating operations, in case we're concatenating
+ * identities, but so that the source or target CRS are not the same as the non identity part. This
+ * happens, for example, when trying to work against a projected CRS with a wrapped geographic CRS
+ * axis in lon/lat order, and with the database providing an operation that uses the same projected
+ * CRS around a geographic CRS with axis in lat/lon order
+ *
+ * @author Andrea Aime - GeoSolutions
+ */
+class ForcedCRSOperation implements CoordinateOperation {
+
+ CoordinateOperation delegate;
+
+ CoordinateReferenceSystem sourceCRS;
+
+ CoordinateReferenceSystem targetCRS;
+
+ public ForcedCRSOperation(CoordinateOperation delegate, CoordinateReferenceSystem sourceCRS,
+ CoordinateReferenceSystem targetCRS) {
+ this.delegate = delegate;
+ this.sourceCRS = sourceCRS;
+ this.targetCRS = targetCRS;
+ }
+
+ public CoordinateReferenceSystem getSourceCRS() {
+ return sourceCRS;
+ }
+
+ public CoordinateReferenceSystem getTargetCRS() {
+ return targetCRS;
+ }
+
+ public ReferenceIdentifier getName() {
+ return delegate.getName();
+ }
+
+ public Collection<GenericName> getAlias() {
+ return delegate.getAlias();
+ }
+
+ public Set<ReferenceIdentifier> getIdentifiers() {
+ return delegate.getIdentifiers();
+ }
+
+ public InternationalString getRemarks() {
+ return delegate.getRemarks();
+ }
+
+ public String toWKT() throws UnsupportedOperationException {
+ return delegate.toWKT();
+ }
+
+ public String getOperationVersion() {
+ return delegate.getOperationVersion();
+ }
+
+ public Collection<PositionalAccuracy> getCoordinateOperationAccuracy() {
+ return delegate.getCoordinateOperationAccuracy();
+ }
+
+ public Extent getDomainOfValidity() {
+ return delegate.getDomainOfValidity();
+ }
+
+ public InternationalString getScope() {
+ return delegate.getScope();
+ }
+
+ public MathTransform getMathTransform() {
+ return delegate.getMathTransform();
+ }
+
+}
|
|
From: <svn...@os...> - 2012-03-04 11:52:55
|
Author: jive
Date: 2012-03-04 03:52:48 -0800 (Sun, 04 Mar 2012)
New Revision: 38606
Modified:
trunk/docs/user/unsupported/process/process-raster.rst
Log:
Fix the different process module pages
Signed-off-by: Jody Garnett <jod...@gm...>
Modified: trunk/docs/user/unsupported/process/process-raster.rst
===================================================================
--- trunk/docs/user/unsupported/process/process-raster.rst 2012-03-04 11:05:40 UTC (rev 38605)
+++ trunk/docs/user/unsupported/process/process-raster.rst 2012-03-04 11:52:48 UTC (rev 38606)
@@ -1,14 +1,14 @@
-Process Feature Plugin
+Process Raster Plugin
----------------------
-The gt-process-feature plugin gathers up a number of high quality processes for working with
-vector information.
+The gt-process-raster plugin a provides a number of ready to use raster processign chains - and
+provide a great example of how to work with rasters.
**Maven**::
<dependency>
<groupId>org.geotools</groupId>
- <artifactId>gt-process-feature</artifactId>
+ <artifactId>gt-process-raster</artifactId>
<version>${geotools.version}</version>
</dependency>
|
Author: aaime
Date: 2012-03-04 03:05:40 -0800 (Sun, 04 Mar 2012)
New Revision: 38605
Modified:
trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/AuthorityBackedFactory.java
trunk/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/CRSTest.java
Log:
[GEOT-4054] When axis flipping is involved AuthorityBackedFactory may not return an operation between the specified source and target crs
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-03-04 11:04:51 UTC (rev 38604)
+++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/AuthorityBackedFactory.java 2012-03-04 11:05:40 UTC (rev 38605)
@@ -35,6 +35,7 @@
import org.geotools.factory.OptionalFactory;
import org.geotools.factory.FactoryRegistryException;
import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.CRS;
import org.geotools.referencing.ReferencingFactoryFinder;
import org.geotools.referencing.factory.BackingStoreException;
import org.geotools.resources.i18n.Loggings;
@@ -369,7 +370,12 @@
throws FactoryException
{
if ((prepend == null || prepend.isIdentity()) && (append == null || append.isIdentity())) {
- return operation;
+ if(!CRS.equalsIgnoreMetadata(sourceCRS, operation.getSourceCRS()) ||
+ !CRS.equalsIgnoreMetadata(targetCRS, operation.getTargetCRS())) {
+ return new ForcedCRSOperation(operation, sourceCRS, targetCRS);
+ } else {
+ return operation;
+ }
}
final Map<String,?> properties = AbstractIdentifiedObject.getProperties(operation);
/*
Modified: trunk/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/CRSTest.java
===================================================================
--- trunk/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/CRSTest.java 2012-03-04 11:04:51 UTC (rev 38604)
+++ trunk/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/CRSTest.java 2012-03-04 11:05:40 UTC (rev 38605)
@@ -32,6 +32,8 @@
import org.opengis.referencing.cs.CoordinateSystemAxis;
import org.opengis.referencing.crs.CRSAuthorityFactory;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.CoordinateOperationFactory;
import org.opengis.referencing.operation.MathTransform;
import org.geotools.factory.Hints;
@@ -439,4 +441,21 @@
assertEquals(20000, src[0], 0.001);
assertEquals(10000, src[1], 0.001);
}
+
+ public void testOperationSourceTarget() throws Exception{
+ // flip one way
+ CoordinateReferenceSystem source = CRS.decode("EPSG:32638", true); // lon/lat
+ CoordinateReferenceSystem target = CRS.decode("EPSG:4326", false); // lat/lon
+ CoordinateOperationFactory coordinateOperationFactory = CRS.getCoordinateOperationFactory(true);
+ CoordinateOperation co = coordinateOperationFactory.createOperation(source, target);
+ assertEquals(source, co.getSourceCRS());
+ assertEquals(target, co.getTargetCRS());
+
+ // flip the other
+ source = CRS.decode("EPSG:32638", false); // lat/lon
+ target = CRS.decode("EPSG:4326", true); // lon/lat
+ co = coordinateOperationFactory.createOperation(source, target);
+ assertEquals(source, co.getSourceCRS());
+ assertEquals(target, co.getTargetCRS());
+ }
}
|
Author: aaime
Date: 2012-03-04 03:04:51 -0800 (Sun, 04 Mar 2012)
New Revision: 38604
Modified:
branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/AuthorityBackedFactory.java
branches/2.7.x/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/CRSTest.java
Log:
[GEOT-4054] When axis flipping is involved AuthorityBackedFactory may not return an operation between the specified source and target crs
Modified: branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/AuthorityBackedFactory.java
===================================================================
--- branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/AuthorityBackedFactory.java 2012-03-04 09:06:29 UTC (rev 38603)
+++ branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/AuthorityBackedFactory.java 2012-03-04 11:04:51 UTC (rev 38604)
@@ -35,6 +35,7 @@
import org.geotools.factory.OptionalFactory;
import org.geotools.factory.FactoryRegistryException;
import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.CRS;
import org.geotools.referencing.ReferencingFactoryFinder;
import org.geotools.referencing.factory.BackingStoreException;
import org.geotools.resources.i18n.Loggings;
@@ -368,7 +369,12 @@
throws FactoryException
{
if ((prepend == null || prepend.isIdentity()) && (append == null || append.isIdentity())) {
- return operation;
+ if(!CRS.equalsIgnoreMetadata(sourceCRS, operation.getSourceCRS()) ||
+ !CRS.equalsIgnoreMetadata(targetCRS, operation.getTargetCRS())) {
+ return new ForcedCRSOperation(operation, sourceCRS, targetCRS);
+ } else {
+ return operation;
+ }
}
final Map<String,?> properties = AbstractIdentifiedObject.getProperties(operation);
/*
Modified: branches/2.7.x/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/CRSTest.java
===================================================================
--- branches/2.7.x/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/CRSTest.java 2012-03-04 09:06:29 UTC (rev 38603)
+++ branches/2.7.x/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/CRSTest.java 2012-03-04 11:04:51 UTC (rev 38604)
@@ -32,6 +32,8 @@
import org.opengis.referencing.cs.CoordinateSystemAxis;
import org.opengis.referencing.crs.CRSAuthorityFactory;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.CoordinateOperationFactory;
import org.opengis.referencing.operation.MathTransform;
import org.geotools.factory.Hints;
@@ -438,4 +440,21 @@
assertEquals(20000, src[0], 0.001);
assertEquals(10000, src[1], 0.001);
}
+
+ public void testOperationSourceTarget() throws Exception{
+ // flip one way
+ CoordinateReferenceSystem source = CRS.decode("EPSG:32638", true); // lon/lat
+ CoordinateReferenceSystem target = CRS.decode("EPSG:4326", false); // lat/lon
+ CoordinateOperationFactory coordinateOperationFactory = CRS.getCoordinateOperationFactory(true);
+ CoordinateOperation co = coordinateOperationFactory.createOperation(source, target);
+ assertEquals(source, co.getSourceCRS());
+ assertEquals(target, co.getTargetCRS());
+
+ // flip the other
+ source = CRS.decode("EPSG:32638", false); // lat/lon
+ target = CRS.decode("EPSG:4326", true); // lon/lat
+ co = coordinateOperationFactory.createOperation(source, target);
+ assertEquals(source, co.getSourceCRS());
+ assertEquals(target, co.getTargetCRS());
+ }
}
|
|
From: <svn...@os...> - 2012-03-04 09:06:36
|
Author: jive Date: 2012-03-04 01:06:29 -0800 (Sun, 04 Mar 2012) New Revision: 38603 Added: trunk/docs/src/main/java/org/geotools/process/ trunk/docs/src/main/java/org/geotools/process/FeatureProcessExamples.java Modified: trunk/docs/user/library/opengis/filter.rst trunk/docs/user/unsupported/process/process-feature.rst Log: code example for TransformProcess Signed-off-by: Jody Garnett <jod...@gm...> Added: trunk/docs/src/main/java/org/geotools/process/FeatureProcessExamples.java =================================================================== --- trunk/docs/src/main/java/org/geotools/process/FeatureProcessExamples.java (rev 0) +++ trunk/docs/src/main/java/org/geotools/process/FeatureProcessExamples.java 2012-03-04 09:06:29 UTC (rev 38603) @@ -0,0 +1,31 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2012, Open Source Geospatial Foundation (OSGeo) + * + * This file is hereby placed into the Public Domain. This means anyone is + * free to do whatever they wish with this file. Use it well and enjoy! + */ +package org.geotools.process; + +import org.geotools.data.simple.SimpleFeatureCollection; +import org.geotools.feature.NameImpl; +import org.geotools.process.feature.gs.TransformProcess; +import org.geotools.util.NullProgressListener; + +public class FeatureProcessExamples { + +public void exampleTransformProcess(SimpleFeatureCollection featureCollection){ + // transform start + String transform = + "the_geom=the_geom\n"+ + "name=name\n"+ + "area=area( the_geom )"; + + TransformProcess process = new TransformProcess(); + + SimpleFeatureCollection features = process.execute( featureCollection, transform ); + // transform end +} +} Property changes on: trunk/docs/src/main/java/org/geotools/process/FeatureProcessExamples.java ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + Id Added: svn:eol-style + native Modified: trunk/docs/user/library/opengis/filter.rst =================================================================== --- trunk/docs/user/library/opengis/filter.rst 2012-03-04 04:06:19 UTC (rev 38602) +++ trunk/docs/user/library/opengis/filter.rst 2012-03-04 09:06:29 UTC (rev 38603) @@ -27,7 +27,7 @@ * Here is an example of using filter and expression together:: - final FilterFactory ff = CommonFactoryFinder.getFilterFactory( null ); + final FilterFactory ff = CommonFactoryFinder.getFilterFactory(); Filter filter = ff.propertyLessThan( ff.property( "AGE"), ff.literal( 12 ) ); SimpleFeatureCollection features = featureSource.getFeatures( filter ); Modified: trunk/docs/user/unsupported/process/process-feature.rst =================================================================== --- trunk/docs/user/unsupported/process/process-feature.rst 2012-03-04 04:06:19 UTC (rev 38602) +++ trunk/docs/user/unsupported/process/process-feature.rst 2012-03-04 09:06:29 UTC (rev 38603) @@ -15,13 +15,14 @@ Transform ^^^^^^^^^ -Transform a feature collection using a series of expressions. +Transform a feature collection using a series of expressions to define each attribute. -The definition of the output feature type can be provided as a Definition data structure or using a simple string format:: +The definition of the output feature type can be provided as a Definition data structure or using a simple string format: - the_geom=the_geom - name=name - area=area( the_geom ) +.. literalinclude:: /../src/main/java/org/geotools/process/FeatureProcessExamples.java + :language: java + :start-after: // transform start + :end-before: // transform end This is a very flexible process which can be used to: |
|
From: <svn...@os...> - 2012-03-04 04:06:27
|
Author: jive
Date: 2012-03-03 20:06:19 -0800 (Sat, 03 Mar 2012)
New Revision: 38602
Added:
trunk/docs/user/unsupported/process/process-feature.rst
trunk/docs/user/unsupported/process/process-geometry.rst
trunk/docs/user/unsupported/process/process-raster.rst
trunk/modules/unsupported/process-feature/src/main/java/org/geotools/process/feature/gs/TransformProcess.java
trunk/modules/unsupported/process-feature/src/test/java/org/geotools/process/feature/gs/TransformProcessTest.java
Removed:
trunk/docs/user/library/data/geometryless.rst
trunk/modules/unsupported/process-feature/src/main/java/org/geotools/process/feature/gs/ReShapeProcess.java
trunk/modules/unsupported/process-feature/src/test/java/org/geotools/process/feature/gs/ReShapeProcessTest.java
Modified:
trunk/docs/user/library/data/index.rst
trunk/docs/user/unsupported/process/index.rst
trunk/modules/unsupported/process-feature/src/main/java/org/geotools/process/feature/gs/FeatureGSProcessFactory.java
Log:
Change over to TransformProcess and update the docs for the website.
Signed-off-by: Jody Garnett <jod...@gm...>
Deleted: trunk/docs/user/library/data/geometryless.rst
===================================================================
--- trunk/docs/user/library/data/geometryless.rst 2012-03-03 16:22:35 UTC (rev 38601)
+++ trunk/docs/user/library/data/geometryless.rst 2012-03-04 04:06:19 UTC (rev 38602)
@@ -1,11 +0,0 @@
-Geometryless Plugin
--------------------
-
-Plugin used to access any database using JDBC. It does not
-assume any form of spatial support and takes care of
-encoding geometry on its own with all spatial operations
-perform in Java on the client side.
-
-No documentation has been provided.
-
-This plugin is no longer avaialble in |release|.
\ No newline at end of file
Modified: trunk/docs/user/library/data/index.rst
===================================================================
--- trunk/docs/user/library/data/index.rst 2012-03-03 16:22:35 UTC (rev 38601)
+++ trunk/docs/user/library/data/index.rst 2012-03-04 04:06:19 UTC (rev 38602)
@@ -68,7 +68,6 @@
dxf
edigeo
excel
- geometryless
georest
ogr
sfs
Modified: trunk/docs/user/unsupported/process/index.rst
===================================================================
--- trunk/docs/user/unsupported/process/index.rst 2012-03-03 16:22:35 UTC (rev 38601)
+++ trunk/docs/user/unsupported/process/index.rst 2012-03-04 04:06:19 UTC (rev 38602)
@@ -10,21 +10,6 @@
<artifactId>gt-process</artifactId>
<version>${geotools.version}</version>
</dependency>
- <dependency>
- <groupId>org.geotools</groupId>
- <artifactId>gt-process-feature</artifactId>
- <version>${geotools.version}</version>
- </dependency>
- <dependency>
- <groupId>org.geotools</groupId>
- <artifactId>gt-process-geometry</artifactId>
- <version>${geotools.version}</version>
- </dependency>
- <dependency>
- <groupId>org.geotools</groupId>
- <artifactId>gt-process-raster</artifactId>
- <version>${geotools.version}</version>
- </dependency>
**Contents**
@@ -39,5 +24,8 @@
:maxdepth: 1
process
+ process-feature
+ process-geometry
+ process-raster
implement
gui
Added: trunk/docs/user/unsupported/process/process-feature.rst
===================================================================
--- trunk/docs/user/unsupported/process/process-feature.rst (rev 0)
+++ trunk/docs/user/unsupported/process/process-feature.rst 2012-03-04 04:06:19 UTC (rev 38602)
@@ -0,0 +1,61 @@
+Process Feature Plugin
+----------------------
+
+The gt-process-feature plugin gathers up a number of high quality processes for working with
+vector information.
+
+**Maven**::
+
+ <dependency>
+ <groupId>org.geotools</groupId>
+ <artifactId>gt-process-feature</artifactId>
+ <version>${geotools.version}</version>
+ </dependency>
+
+Transform
+^^^^^^^^^
+
+Transform a feature collection using a series of expressions.
+
+The definition of the output feature type can be provided as a Definition data structure or using a simple string format::
+
+ the_geom=the_geom
+ name=name
+ area=area( the_geom )
+
+This is a very flexible process which can be used to:
+
+* Change the order of attributes - resulting in a new feature type::
+
+ INPUT Schema DEFINITION OUTPUT Schema
+ the_geom: Polygon the_geom the_geom: Polygon
+ name: String id id: Long
+ id: Long name name: String
+ description: String description description: String
+
+* Rename or remove attributes - resulting in a new feature type::
+
+ INPUT Schema DEFINITION OUTPUT Schema
+ the_geom: Polygon the_geom the_geom: Polygon
+ name: String id_code=id id_code: Long
+ id: Long summary=description summary: String
+ description: String
+
+* Process geometry - using functions like "the_geom=simplify( the_geom, 2.0 )" or "the_geom=centriod( the_geom )"::
+
+ INPUT Schema DEFINITION OUTPUT Schema
+ the_geom: Polygon the_geom=centriod(the_geom) the_geom: Point
+ name: String name name: String
+ id: Long id id: Long
+ description: String description description: String
+
+* Generate additional attributes using the form: area=area( the_geom )::
+
+ INPUT Schema DEFINITION OUTPUT Schema
+ the_geom: Polygon the_geom=centriod(the_geom) the_geom: Point
+ name: String name name: String
+ id: Long id id: Long
+ description: String description description: String
+ area=area( the_geom) area: Double
+ text=concatenate(name,'-',id) text: String
+
\ No newline at end of file
Added: trunk/docs/user/unsupported/process/process-geometry.rst
===================================================================
--- trunk/docs/user/unsupported/process/process-geometry.rst (rev 0)
+++ trunk/docs/user/unsupported/process/process-geometry.rst 2012-03-04 04:06:19 UTC (rev 38602)
@@ -0,0 +1,13 @@
+Process Geometry Plugin
+-----------------------
+
+The gt-process-geometry focuses on working with JTS Geometry objects.
+
+**Maven**::
+
+ <dependency>
+ <groupId>org.geotools</groupId>
+ <artifactId>gt-process-geometry</artifactId>
+ <version>${geotools.version}</version>
+ </dependency>
+
Added: trunk/docs/user/unsupported/process/process-raster.rst
===================================================================
--- trunk/docs/user/unsupported/process/process-raster.rst (rev 0)
+++ trunk/docs/user/unsupported/process/process-raster.rst 2012-03-04 04:06:19 UTC (rev 38602)
@@ -0,0 +1,14 @@
+Process Feature Plugin
+----------------------
+
+The gt-process-feature plugin gathers up a number of high quality processes for working with
+vector information.
+
+**Maven**::
+
+ <dependency>
+ <groupId>org.geotools</groupId>
+ <artifactId>gt-process-feature</artifactId>
+ <version>${geotools.version}</version>
+ </dependency>
+
Modified: trunk/modules/unsupported/process-feature/src/main/java/org/geotools/process/feature/gs/FeatureGSProcessFactory.java
===================================================================
--- trunk/modules/unsupported/process-feature/src/main/java/org/geotools/process/feature/gs/FeatureGSProcessFactory.java 2012-03-03 16:22:35 UTC (rev 38601)
+++ trunk/modules/unsupported/process-feature/src/main/java/org/geotools/process/feature/gs/FeatureGSProcessFactory.java 2012-03-04 04:06:19 UTC (rev 38602)
@@ -59,7 +59,7 @@
UnionFeatureCollection.class,
UniqueProcess.class,
VectorZonalStatistics.class,
- ReShapeProcess.class);
+ TransformProcess.class);
}
}
Deleted: trunk/modules/unsupported/process-feature/src/main/java/org/geotools/process/feature/gs/ReShapeProcess.java
===================================================================
--- trunk/modules/unsupported/process-feature/src/main/java/org/geotools/process/feature/gs/ReShapeProcess.java 2012-03-03 16:22:35 UTC (rev 38601)
+++ trunk/modules/unsupported/process-feature/src/main/java/org/geotools/process/feature/gs/ReShapeProcess.java 2012-03-04 04:06:19 UTC (rev 38602)
@@ -1,311 +0,0 @@
-/*
- * GeoTools - The Open Source Java GIS Toolkit
- * http://geotools.org
- *
- * (C) 2011, Open Source Geospatial Foundation (OSGeo)
- * (C) 2007-2011 Refractions Research
- *
- * 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.process.feature.gs;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-import org.geotools.data.simple.SimpleFeatureCollection;
-import org.geotools.data.simple.SimpleFeatureIterator;
-import org.geotools.feature.collection.DecoratingSimpleFeatureCollection;
-import org.geotools.feature.simple.SimpleFeatureBuilder;
-import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
-import org.geotools.filter.text.cql2.CQL;
-import org.geotools.filter.text.cql2.CQLException;
-import org.geotools.filter.text.ecql.ECQL;
-import org.geotools.process.ProcessException;
-import org.geotools.process.factory.DescribeParameter;
-import org.geotools.process.factory.DescribeProcess;
-import org.geotools.process.factory.DescribeResult;
-import org.geotools.process.gs.GSProcess;
-import org.geotools.process.gs.WrappingIterator;
-import org.opengis.feature.simple.SimpleFeature;
-import org.opengis.feature.simple.SimpleFeatureType;
-import org.opengis.feature.type.AttributeDescriptor;
-import org.opengis.feature.type.AttributeType;
-import org.opengis.feature.type.GeometryType;
-import org.opengis.filter.expression.Expression;
-import org.opengis.filter.expression.PropertyName;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.simplify.DouglasPeuckerSimplifier;
-import com.vividsolutions.jts.simplify.TopologyPreservingSimplifier;
-
-/**
- * Used to reshape a feature collection as defined using a series of expressions.
- * <p>
- * This is a port of the uDig Reshape operation to the GeoTools process framework.
- * <p>
- * This is a very flexable process which can be used to:
- * <ul>
- * <li>Change the order of attribtues - resulting in a new feature type</li>
- * <li>Rename attribtues - resulting in a new feature type</li>
- * <li>Process geometry - using functions like "the_geom=simplify( the_geom, 2.0 )" or "the_geom=centriod( the_geom )"</li>
- * <li>Generate additional attribtues using the form: area=area( the_geom )</li>
- * </ul>
- * <p>
- * The definition of the output feature type can be provided as a data structure or using a simple string format:
- *
- * <pre>
- * the_geom=the_geom
- * name=name
- * area=area( the_geom )
- * </pre>
- *
- * @author Jody Garnett (LISAsoft)
- *
- * @source $URL$
- */
-@DescribeProcess(title = "simplify", description = "Simplifies the geometry")
-public class ReShapeProcess implements GSProcess {
- /**
- * Definition of an attribute used during reshape.
- * <p>
- * Note this definition is terse as we are gathering the details from the origional FeatureType.
- *
- * @author jody
- */
- public static class Definition {
- /** Name of the AttribtueDescriptor to generate */
- public String name;
-
- /** Expression used to generate the target calue; most simply a PropertyName */
- public Expression expression;
-
- /** Class binding (if known) */
- public Class<?> binding;
- }
- @DescribeResult(name = "result", description = "rehaped feature collection")
- public SimpleFeatureCollection execute(
- @DescribeParameter(name = "features", description = "The feature collection to rehaped") SimpleFeatureCollection features,
- @DescribeParameter(name = "definition", description = "Definition of output feature type using attribute=expr pairs") String definition)
- throws ProcessException {
- if (definition == null) {
- return features; // no change
- }
- List<Definition> list = toDefinition(definition);
- return executeList(features, list);
- }
-
- @DescribeResult(name = "result", description = "rehaped feature collection")
- public SimpleFeatureCollection executeList(
- @DescribeParameter(name = "features", description = "The feature collection to rehaped") SimpleFeatureCollection features,
- @DescribeParameter(name = "list", description = "List of Definitions for the output feature type") List<Definition> list)
- throws ProcessException {
- if (list == null) {
- return features; // no change
- }
- return new ReshapeFeatureCollection(features, list);
- }
-
-
- //
- // helper methods made static for ease of JUnit testing
- //
-
- /**
- * Parse out a list of {@link Definition} from the provided text description.
- * <p>
- * The format expected here is one definition per line; using the format "name=...expression..".
- *
- * @param definition
- * @return List of definition
- */
- public static List<Definition> toDefinition(String definition) {
- List<Definition> list = new ArrayList<Definition>();
- HashSet<String> check = new HashSet<String>();
-
- // clean up cross platform differences of line feed
- definition = definition.replaceAll("\r", "\n").replaceAll("[\n\r][\n\r]", "\n");
-
- for (String line : definition.split("\n")) {
- int mark = line.indexOf("=");
- if (mark != -1) {
- String name = line.substring(0, mark).trim();
- String expressionDefinition = line.substring(mark + 1).trim();
-
- if (check.contains(name)) {
- throw new IllegalArgumentException("ReShape definition " + name
- + " already in use");
- }
- Expression expression;
- try {
- expression = ECQL.toExpression(expressionDefinition);
- } catch (CQLException e) {
- throw new IllegalArgumentException("Reshape unable to parse " + name + "="
- + expressionDefinition + " " + e, e);
- }
- Definition def = new Definition();
- def.name = name;
- def.expression = expression;
- list.add(def);
- check.add(name); // to catch duplicates!
- }
- }
- return list;
- }
-
- public static SimpleFeatureType toReShapeFeatureType(SimpleFeatureCollection delegate,
- List<Definition> definitionList) {
-
- SimpleFeature sample = null;
- SimpleFeatureIterator iterator = delegate.features();
- try {
- if( iterator.hasNext() ){
- sample = iterator.next();
- }
- }
- finally {
- iterator.close(); // good bye
- }
-
- SimpleFeatureTypeBuilder build = new SimpleFeatureTypeBuilder();
- SimpleFeatureType origional = delegate.getSchema();
-
- for( Definition def : definitionList ){
- String name = def.name;
- Expression expression = def.expression;
-
- Object value = null;
- if( sample != null ){
- value = expression.evaluate(sample);
- }
- Class<?> binding = def.binding; // make use of any default binding hint provided by user
- if( value == null){
- if( expression instanceof PropertyName){
- PropertyName propertyName = (PropertyName)expression;
- String path = propertyName.getPropertyName();
- AttributeDescriptor descriptor = origional.getDescriptor( name );
- AttributeType attributeType = descriptor.getType();
- binding = attributeType.getBinding();
- }
- } else {
- binding = value.getClass();
- }
-
- if( binding ==null ){
- // note we could consider scanning through additional samples until we get a non null hit
- throw new IllegalArgumentException("Unable to determine type for "+name);
- }
-
- if( Geometry.class.isAssignableFrom( binding )){
- CoordinateReferenceSystem crs;
- AttributeType originalAttributeType = origional.getType(name);
- if( originalAttributeType != null && originalAttributeType instanceof GeometryType ) {
- GeometryType geometryType = (GeometryType)originalAttributeType;
- crs = geometryType.getCoordinateReferenceSystem();
- } else {
- crs = origional.getCoordinateReferenceSystem();
- }
- build.crs(crs);
- build.add(name, binding);
- }
- else {
- build.add(name, binding);
- }
- }
- build.setName( origional.getTypeName() );
- return build.buildFeatureType();
- }
-
- //
- // helper classes responsible for most of the work
- //
-
- /**
- * ReshapeFeatureCollection obtaining feature type by processing the list of definitions
- * against the origional delegate feature collection.
- * @author jody
- */
- static class ReshapeFeatureCollection extends DecoratingSimpleFeatureCollection {
- List<Definition> definition;
- SimpleFeatureType schema;
-
- public ReshapeFeatureCollection(SimpleFeatureCollection delegate, List<Definition> definition) {
- super(delegate);
- this.definition = definition;
- this.schema = toReShapeFeatureType( delegate, definition );
- }
- @Override
- public SimpleFeatureType getSchema() {
- return schema;
- }
-
- @Override
- public SimpleFeatureIterator features() {
- return new ReshapeFeatureIterator(delegate.features(), definition, schema);
- }
-
- @Override
- public Iterator<SimpleFeature> iterator() {
- return new WrappingIterator(features());
- }
-
- @Override
- public void close(Iterator<SimpleFeature> close) {
- if (close instanceof WrappingIterator) {
- ((WrappingIterator) close).close();
- }
- }
- }
- /**
- * Process one feature at time; obtaining values by evaulating the provided list of definitions.
- *
- * @author jody
- */
- static class ReshapeFeatureIterator implements SimpleFeatureIterator {
- SimpleFeatureIterator delegate;
-
- List<Definition> definition;
-
- SimpleFeatureBuilder fb;
-
- public ReshapeFeatureIterator(SimpleFeatureIterator delegate, List<Definition> definition,
- SimpleFeatureType schema) {
- this.delegate = delegate;
- this.definition = definition;
- fb = new SimpleFeatureBuilder(schema);
- }
-
-
- public void close() {
- delegate.close();
- }
-
- public boolean hasNext() {
- return delegate.hasNext();
- }
-
- public SimpleFeature next() throws NoSuchElementException {
- SimpleFeature feature = delegate.next();
-
- for( Definition def : definition ){
- Object value = def.expression.evaluate(feature);
- fb.add( value );
- }
- SimpleFeature created = fb.buildFeature(feature.getID());
- return created;
- }
-
- }
-
-}
Copied: trunk/modules/unsupported/process-feature/src/main/java/org/geotools/process/feature/gs/TransformProcess.java (from rev 38592, trunk/modules/unsupported/process-feature/src/main/java/org/geotools/process/feature/gs/ReShapeProcess.java)
===================================================================
--- trunk/modules/unsupported/process-feature/src/main/java/org/geotools/process/feature/gs/TransformProcess.java (rev 0)
+++ trunk/modules/unsupported/process-feature/src/main/java/org/geotools/process/feature/gs/TransformProcess.java 2012-03-04 04:06:19 UTC (rev 38602)
@@ -0,0 +1,339 @@
+/*
+ * GeoTools - The Open Source Java GIS Toolkit
+ * http://geotools.org
+ *
+ * (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ * (C) 2007-2011 Refractions Research
+ *
+ * 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.process.feature.gs;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureIterator;
+import org.geotools.feature.collection.DecoratingSimpleFeatureCollection;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
+import org.geotools.filter.text.cql2.CQL;
+import org.geotools.filter.text.cql2.CQLException;
+import org.geotools.filter.text.ecql.ECQL;
+import org.geotools.process.ProcessException;
+import org.geotools.process.factory.DescribeParameter;
+import org.geotools.process.factory.DescribeProcess;
+import org.geotools.process.factory.DescribeResult;
+import org.geotools.process.gs.GSProcess;
+import org.geotools.process.gs.WrappingIterator;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.AttributeType;
+import org.opengis.feature.type.GeometryType;
+import org.opengis.filter.expression.Expression;
+import org.opengis.filter.expression.PropertyName;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.simplify.DouglasPeuckerSimplifier;
+import com.vividsolutions.jts.simplify.TopologyPreservingSimplifier;
+
+/**
+ * Used to transform a feature collection as defined using a series of expressions.
+ * <p>
+ * The definition of the output feature type can be provided as a {@link Definition} data structure
+ * or using a simple string format:
+ *
+ * <pre>
+ * the_geom=the_geom
+ * name=name
+ * area=area( the_geom )
+ * </pre>
+
+ * <p>
+ * This is a very flexible process which can be used to:
+ * <ul>
+ * <li>Change the order of attributes - resulting in a new feature type:<pre>
+ * INPUT Schema DEFINITION OUTPUT Schema
+ * the_geom: Polygon the_geom the_geom: Polygon
+ * name: String id id: Long
+ * id: Long name name: String
+ * description: String description description: String
+ * </pre></li>
+ * <li>Rename or remove attributes - resulting in a new feature type:<pre>
+ * INPUT Schema DEFINITION OUTPUT Schema
+ * the_geom: Polygon the_geom the_geom: Polygon
+ * name: String id_code=id id_code: Long
+ * id: Long summary=description summary: String
+ * description: String
+ * </pre></li>
+ * <li>Process geometry - using functions like "the_geom=simplify( the_geom, 2.0 )" or "the_geom=centriod( the_geom )":<pre>
+ * INPUT Schema DEFINITION OUTPUT Schema
+ * the_geom: Polygon the_geom=centriod(the_geom) the_geom: Point
+ * name: String name name: String
+ * id: Long id id: Long
+ * description: String description description: String
+ * </pre></li>
+ * <li>Generate additional attributes using the form: area=area( the_geom ):<pre>
+ * INPUT Schema DEFINITION OUTPUT Schema
+ * the_geom: Polygon the_geom=centriod(the_geom) the_geom: Point
+ * name: String name name: String
+ * id: Long id id: Long
+ * description: String description description: String
+ * area=area( the_geom) area: Double
+ * text=concatenate(name,'-',id) text: String
+ * </pre></li>
+ * </ul>
+ * <p>
+ * This is a port of the uDig "reshape" operation to the GeoTools process framework.
+ *
+ * @author Jody Garnett (LISAsoft)
+ *
+ * @source $URL$
+ */
+@DescribeProcess(title = "transform", description = "Transform feature collection")
+public class TransformProcess implements GSProcess {
+ /**
+ * Definition of an attribute used during transform
+ * <p>
+ * Note this definition is terse as we are gathering the details from the origional FeatureType.
+ *
+ * @author jody
+ */
+ public static class Definition {
+ /** Name of the AttribtueDescriptor to generate */
+ public String name;
+
+ /** Expression used to generate the target calue; most simply a PropertyName */
+ public Expression expression;
+
+ /** Class binding (if known) */
+ public Class<?> binding;
+ }
+ @DescribeResult(name = "result", description = "transformed features")
+ public SimpleFeatureCollection execute(
+ @DescribeParameter(name = "features", description = "The feature collection to transform") SimpleFeatureCollection features,
+ @DescribeParameter(name = "transform", description = "Transform defined with one 'attribute=expr' pair per line") String transform)
+ throws ProcessException {
+ if (transform == null) {
+ return features; // no change
+ }
+ List<Definition> list = toDefinition(transform);
+ return executeList(features, list);
+ }
+
+ @DescribeResult(name = "result", description = "transformed features")
+ public SimpleFeatureCollection executeList(
+ @DescribeParameter(name = "features", description = "The feature collection to rehaped") SimpleFeatureCollection features,
+ @DescribeParameter(name = "transform", description = "List of Definitions for the output feature type") List<Definition> transform)
+ throws ProcessException {
+ if (transform == null) {
+ return features; // no change
+ }
+ return new ReshapeFeatureCollection(features, transform);
+ }
+
+
+ //
+ // helper methods made static for ease of JUnit testing
+ //
+
+ /**
+ * Parse out a list of {@link Definition} from the provided text description.
+ * <p>
+ * The format expected here is one definition per line; using the format "name=...expression..".
+ *
+ * @param definition
+ * @return List of definition
+ */
+ public static List<Definition> toDefinition(String definition) {
+ List<Definition> list = new ArrayList<Definition>();
+ HashSet<String> check = new HashSet<String>();
+
+ // clean up cross platform differences of line feed
+ definition = definition.replaceAll("\r", "\n").replaceAll("[\n\r][\n\r]", "\n");
+
+ for (String line : definition.split("\n")) {
+ int mark = line.indexOf("=");
+ if (mark != -1) {
+ String name = line.substring(0, mark).trim();
+ String expressionDefinition = line.substring(mark + 1).trim();
+
+ if (check.contains(name)) {
+ throw new IllegalArgumentException("ReShape definition " + name
+ + " already in use");
+ }
+ Expression expression;
+ try {
+ expression = ECQL.toExpression(expressionDefinition);
+ } catch (CQLException e) {
+ throw new IllegalArgumentException("Reshape unable to parse " + name + "="
+ + expressionDefinition + " " + e, e);
+ }
+ Definition def = new Definition();
+ def.name = name;
+ def.expression = expression;
+ list.add(def);
+ check.add(name); // to catch duplicates!
+ }
+ }
+ return list;
+ }
+
+ public static SimpleFeatureType toReShapeFeatureType(SimpleFeatureCollection delegate,
+ List<Definition> definitionList) {
+
+ SimpleFeature sample = null;
+ SimpleFeatureIterator iterator = delegate.features();
+ try {
+ if( iterator.hasNext() ){
+ sample = iterator.next();
+ }
+ }
+ finally {
+ iterator.close(); // good bye
+ }
+
+ SimpleFeatureTypeBuilder build = new SimpleFeatureTypeBuilder();
+ SimpleFeatureType origional = delegate.getSchema();
+
+ for( Definition def : definitionList ){
+ String name = def.name;
+ Expression expression = def.expression;
+
+ Object value = null;
+ if( sample != null ){
+ value = expression.evaluate(sample);
+ }
+ Class<?> binding = def.binding; // make use of any default binding hint provided by user
+ if( value == null){
+ if( expression instanceof PropertyName){
+ PropertyName propertyName = (PropertyName)expression;
+ String path = propertyName.getPropertyName();
+ AttributeDescriptor descriptor = origional.getDescriptor( name );
+ AttributeType attributeType = descriptor.getType();
+ binding = attributeType.getBinding();
+ }
+ } else {
+ binding = value.getClass();
+ }
+
+ if( binding ==null ){
+ // note we could consider scanning through additional samples until we get a non null hit
+ throw new IllegalArgumentException("Unable to determine type for "+name);
+ }
+
+ if( Geometry.class.isAssignableFrom( binding )){
+ CoordinateReferenceSystem crs;
+ AttributeType originalAttributeType = origional.getType(name);
+ if( originalAttributeType != null && originalAttributeType instanceof GeometryType ) {
+ GeometryType geometryType = (GeometryType)originalAttributeType;
+ crs = geometryType.getCoordinateReferenceSystem();
+ } else {
+ crs = origional.getCoordinateReferenceSystem();
+ }
+ build.crs(crs);
+ build.add(name, binding);
+ }
+ else {
+ build.add(name, binding);
+ }
+ }
+ build.setName( origional.getTypeName() );
+ return build.buildFeatureType();
+ }
+
+ //
+ // helper classes responsible for most of the work
+ //
+
+ /**
+ * ReshapeFeatureCollection obtaining feature type by processing the list of definitions
+ * against the origional delegate feature collection.
+ * @author jody
+ */
+ static class ReshapeFeatureCollection extends DecoratingSimpleFeatureCollection {
+ List<Definition> definition;
+ SimpleFeatureType schema;
+
+ public ReshapeFeatureCollection(SimpleFeatureCollection delegate, List<Definition> definition) {
+ super(delegate);
+ this.definition = definition;
+ this.schema = toReShapeFeatureType( delegate, definition );
+ }
+ @Override
+ public SimpleFeatureType getSchema() {
+ return schema;
+ }
+
+ @Override
+ public SimpleFeatureIterator features() {
+ return new ReshapeFeatureIterator(delegate.features(), definition, schema);
+ }
+
+ @Override
+ public Iterator<SimpleFeature> iterator() {
+ return new WrappingIterator(features());
+ }
+
+ @Override
+ public void close(Iterator<SimpleFeature> close) {
+ if (close instanceof WrappingIterator) {
+ ((WrappingIterator) close).close();
+ }
+ }
+ }
+ /**
+ * Process one feature at time; obtaining values by evaulating the provided list of definitions.
+ *
+ * @author jody
+ */
+ static class ReshapeFeatureIterator implements SimpleFeatureIterator {
+ SimpleFeatureIterator delegate;
+
+ List<Definition> definition;
+
+ SimpleFeatureBuilder fb;
+
+ public ReshapeFeatureIterator(SimpleFeatureIterator delegate, List<Definition> definition,
+ SimpleFeatureType schema) {
+ this.delegate = delegate;
+ this.definition = definition;
+ fb = new SimpleFeatureBuilder(schema);
+ }
+
+
+ public void close() {
+ delegate.close();
+ }
+
+ public boolean hasNext() {
+ return delegate.hasNext();
+ }
+
+ public SimpleFeature next() throws NoSuchElementException {
+ SimpleFeature feature = delegate.next();
+
+ for( Definition def : definition ){
+ Object value = def.expression.evaluate(feature);
+ fb.add( value );
+ }
+ SimpleFeature created = fb.buildFeature(feature.getID());
+ return created;
+ }
+
+ }
+
+}
Property changes on: trunk/modules/unsupported/process-feature/src/main/java/org/geotools/process/feature/gs/TransformProcess.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Id
Added: svn:eol-style
+ native
Deleted: trunk/modules/unsupported/process-feature/src/test/java/org/geotools/process/feature/gs/ReShapeProcessTest.java
===================================================================
--- trunk/modules/unsupported/process-feature/src/test/java/org/geotools/process/feature/gs/ReShapeProcessTest.java 2012-03-03 16:22:35 UTC (rev 38601)
+++ trunk/modules/unsupported/process-feature/src/test/java/org/geotools/process/feature/gs/ReShapeProcessTest.java 2012-03-04 04:06:19 UTC (rev 38602)
@@ -1,92 +0,0 @@
-/*
- * GeoTools - The Open Source Java GIS Toolkit
- * http://geotools.org
- *
- * (C) 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.process.feature.gs;
-
-
-import static org.junit.Assert.*;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Set;
-
-import org.geotools.data.DataStore;
-import org.geotools.data.property.PropertyDataStore;
-import org.geotools.data.simple.SimpleFeatureCollection;
-import org.geotools.data.simple.SimpleFeatureSource;
-import org.geotools.process.feature.gs.AggregateProcess.AggregationFunction;
-import org.geotools.process.feature.gs.AggregateProcess.Results;
-import org.geotools.process.feature.gs.ReShapeProcess.Definition;
-import org.geotools.test.TestData;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.opengis.feature.simple.SimpleFeatureType;
-import org.opengis.feature.type.AttributeDescriptor;
-import org.opengis.filter.expression.PropertyName;
-
-/**
- *
- *
- * @source $URL$
- */
-public class ReShapeProcessTest {
- DataStore bugs;
-
- @Before
- public void setup() throws IOException {
- File file = TestData.file(this, null );
- bugs = new PropertyDataStore( file );
- }
- @After
- public void tearDown(){
- bugs.dispose();
- }
-
-
- @Test
- public void testDefinition() throws Exception {
- String definition = "the_geom=the_geom";
- List<Definition> def = ReShapeProcess.toDefinition( definition );
-
- assertEquals( 1, def.size() );
-
- assertEquals( "the_geom", def.get(0).name );
- assertTrue( def.get(0).expression instanceof PropertyName );
- }
-
- @Test
- public void testSum() throws Exception {
- SimpleFeatureSource source = bugs.getFeatureSource("bugsites");
-
-
- ReShapeProcess process = new ReShapeProcess();
-
- String definition = "the_geom=the_geom\nnumber=cat";
- SimpleFeatureCollection origional = source.getFeatures();
- SimpleFeatureCollection result = process.execute( origional, definition );
-
- assertEquals( origional.size(), result.size() );
-
- SimpleFeatureType schema = result.getSchema();
- AttributeDescriptor number = schema.getDescriptor("number");
- assertTrue( Long.class.isAssignableFrom( number.getType().getBinding() ) );
-
- }
-
-}
Copied: trunk/modules/unsupported/process-feature/src/test/java/org/geotools/process/feature/gs/TransformProcessTest.java (from rev 38592, trunk/modules/unsupported/process-feature/src/test/java/org/geotools/process/feature/gs/ReShapeProcessTest.java)
===================================================================
--- trunk/modules/unsupported/process-feature/src/test/java/org/geotools/process/feature/gs/TransformProcessTest.java (rev 0)
+++ trunk/modules/unsupported/process-feature/src/test/java/org/geotools/process/feature/gs/TransformProcessTest.java 2012-03-04 04:06:19 UTC (rev 38602)
@@ -0,0 +1,92 @@
+/*
+ * GeoTools - The Open Source Java GIS Toolkit
+ * http://geotools.org
+ *
+ * (C) 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.process.feature.gs;
+
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+
+import org.geotools.data.DataStore;
+import org.geotools.data.property.PropertyDataStore;
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureSource;
+import org.geotools.process.feature.gs.AggregateProcess.AggregationFunction;
+import org.geotools.process.feature.gs.AggregateProcess.Results;
+import org.geotools.process.feature.gs.TransformProcess.Definition;
+import org.geotools.test.TestData;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.filter.expression.PropertyName;
+
+/**
+ *
+ *
+ * @source $URL$
+ */
+public class TransformProcessTest {
+ DataStore bugs;
+
+ @Before
+ public void setup() throws IOException {
+ File file = TestData.file(this, null );
+ bugs = new PropertyDataStore( file );
+ }
+ @After
+ public void tearDown(){
+ bugs.dispose();
+ }
+
+
+ @Test
+ public void testDefinition() throws Exception {
+ String definition = "the_geom=the_geom";
+ List<Definition> def = TransformProcess.toDefinition( definition );
+
+ assertEquals( 1, def.size() );
+
+ assertEquals( "the_geom", def.get(0).name );
+ assertTrue( def.get(0).expression instanceof PropertyName );
+ }
+
+ @Test
+ public void testSum() throws Exception {
+ SimpleFeatureSource source = bugs.getFeatureSource("bugsites");
+
+
+ TransformProcess process = new TransformProcess();
+
+ String definition = "the_geom=the_geom\nnumber=cat";
+ SimpleFeatureCollection origional = source.getFeatures();
+ SimpleFeatureCollection result = process.execute( origional, definition );
+
+ assertEquals( origional.size(), result.size() );
+
+ SimpleFeatureType schema = result.getSchema();
+ AttributeDescriptor number = schema.getDescriptor("number");
+ assertTrue( Long.class.isAssignableFrom( number.getType().getBinding() ) );
+
+ }
+
+}
Property changes on: trunk/modules/unsupported/process-feature/src/test/java/org/geotools/process/feature/gs/TransformProcessTest.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Id
Added: svn:eol-style
+ native
|
|
From: <svn...@os...> - 2012-03-03 16:22:41
|
Author: jdeolive
Date: 2012-03-03 08:22:35 -0800 (Sat, 03 Mar 2012)
New Revision: 38601
Modified:
branches/2.7.x/modules/library/metadata/pom.xml
branches/2.7.x/pom.xml
Log:
GEOT-4042, removing git revision info plugin
Modified: branches/2.7.x/modules/library/metadata/pom.xml
===================================================================
--- branches/2.7.x/modules/library/metadata/pom.xml 2012-03-03 16:22:20 UTC (rev 38600)
+++ branches/2.7.x/modules/library/metadata/pom.xml 2012-03-03 16:22:35 UTC (rev 38601)
@@ -137,30 +137,4 @@
</resources>
</build>
- <profiles>
- <profile>
- <id>gitinfo</id>
- <build>
- <plugins>
- <plugin>
- <groupId>pl.project13.maven</groupId>
- <artifactId>git-commit-id-plugin</artifactId>
- <executions>
- <execution>
- <phase>generate-resources</phase>
- <goals>
- <goal>revision</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <generateGitPropertiesFile>true</generateGitPropertiesFile>
- <generateGitPropertiesFilename>target/classes/git.properties</generateGitPropertiesFilename>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-
</project>
Modified: branches/2.7.x/pom.xml
===================================================================
--- branches/2.7.x/pom.xml 2012-03-03 16:22:20 UTC (rev 38600)
+++ branches/2.7.x/pom.xml 2012-03-03 16:22:35 UTC (rev 38601)
@@ -1182,15 +1182,6 @@
</configuration>
</plugin>
- <!-- ======================================================= -->
- <!-- Git revision info. -->
- <!-- ======================================================= -->
- <plugin>
- <groupId>pl.project13.maven</groupId>
- <artifactId>git-commit-id-plugin</artifactId>
- <version>1.9</version>
- </plugin>
-
</plugins>
</build>
|
|
From: <svn...@os...> - 2012-03-03 16:22:26
|
Author: jdeolive
Date: 2012-03-03 08:22:20 -0800 (Sat, 03 Mar 2012)
New Revision: 38600
Modified:
trunk/modules/library/metadata/pom.xml
trunk/pom.xml
Log:
GEOT-4042, removing git revision info plugin
Modified: trunk/modules/library/metadata/pom.xml
===================================================================
--- trunk/modules/library/metadata/pom.xml 2012-03-03 14:24:31 UTC (rev 38599)
+++ trunk/modules/library/metadata/pom.xml 2012-03-03 16:22:20 UTC (rev 38600)
@@ -137,39 +137,4 @@
</resources>
</build>
- <profiles>
- <profile>
- <id>gitinfo</id>
- <activation>
- <file>
- <!-- .git directory specified relative to working directory, so
- this profile only engaged when building from root. This is
- changed/fixed in maven 3, so when build server switches to
- maven 3 change this to '../../../.git' -->
- <exists>.git</exists>
- </file>
- </activation>
- <build>
- <plugins>
- <plugin>
- <groupId>pl.project13.maven</groupId>
- <artifactId>git-commit-id-plugin</artifactId>
- <executions>
- <execution>
- <phase>generate-resources</phase>
- <goals>
- <goal>revision</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <generateGitPropertiesFile>true</generateGitPropertiesFile>
- <generateGitPropertiesFilename>target/classes/git.properties</generateGitPropertiesFilename>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-
</project>
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2012-03-03 14:24:31 UTC (rev 38599)
+++ trunk/pom.xml 2012-03-03 16:22:20 UTC (rev 38600)
@@ -1284,15 +1284,6 @@
</configuration>
</plugin>
- <!-- ======================================================= -->
- <!-- Git revision info. -->
- <!-- ======================================================= -->
- <plugin>
- <groupId>pl.project13.maven</groupId>
- <artifactId>git-commit-id-plugin</artifactId>
- <version>1.9</version>
- </plugin>
-
</plugins>
</build>
|
|
From: <svn...@os...> - 2012-03-03 14:24:38
|
Author: aaime
Date: 2012-03-03 06:24:31 -0800 (Sat, 03 Mar 2012)
New Revision: 38599
Modified:
branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/DirectEpsgFactory.java
Log:
Fixing build by working around a H2 bug, reworking some atrocious code handling resultset closing in the process
Modified: branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/DirectEpsgFactory.java
===================================================================
--- branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/DirectEpsgFactory.java 2012-03-03 14:24:17 UTC (rev 38598)
+++ branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/DirectEpsgFactory.java 2012-03-03 14:24:31 UTC (rev 38599)
@@ -2491,6 +2491,7 @@
{
ensureNonNull("code", code);
CoordinateOperation returnValue = null;
+ ResultSet result = null;
try {
final String primaryKey = toPrimaryKey(CoordinateOperation.class, code,
"[Coordinate_Operation]", "COORD_OP_CODE", "COORD_OP_NAME");
@@ -2509,8 +2510,8 @@
+ " FROM [Coordinate_Operation]"
+ " WHERE COORD_OP_CODE = ?");
stmt.setInt(1, Integer.parseInt(primaryKey));
- ResultSet result = stmt.executeQuery();
- while (result.next()) {
+ result = stmt.executeQuery();
+ while (hasNext(result)) {
final String epsg = getString(result, 1, code);
final String name = getString(result, 2, code);
final String type = getString(result, 3, code).trim().toLowerCase();
@@ -2579,7 +2580,6 @@
try {
num = Integer.parseInt(methodCode);
} catch (NumberFormatException exception) {
- result.close();
throw new FactoryException(exception);
}
isBursaWolf = (num>=BURSA_WOLF_MIN_CODE && num<=BURSA_WOLF_MAX_CODE);
@@ -2654,7 +2654,6 @@
* to avoid loading the quite large Geotools's implementation of this factory,
* and also because it is not part of FactoryGroup anyway.
*/
- result.close();
result = null;
final PreparedStatement cstmt = prepareStatement("ConcatenatedOperation",
"SELECT SINGLE_OPERATION_CODE"
@@ -2708,7 +2707,6 @@
parameters.parameter("tgt_dim").setValue(targetCRS.getCoordinateSystem().getDimension());
}
} catch (ParameterNotFoundException exception) {
- result.close();
throw new FactoryException(Errors.format(
ErrorKeys.GEOTOOLS_EXTENSION_REQUIRED_$1,
method.getName().getCode(), exception));
@@ -2723,7 +2721,6 @@
} else if (isConversion) {
expected = Conversion.class;
} else {
- result.close();
throw new FactoryException(Errors.format(ErrorKeys.UNKNOW_TYPE_$1, type));
}
final MathTransform mt = factories.getMathTransformFactory().createBaseToDerived(
@@ -2733,15 +2730,17 @@
mt, method, expected);
}
returnValue = ensureSingleton(operation, returnValue, code);
- if (result == null) {
- // Bypass the 'result.close()' line below:
- // the ResultSet has already been closed.
- return returnValue;
- }
}
- result.close();
} catch (SQLException exception) {
throw databaseFailure(CoordinateOperation.class, code, exception);
+ } finally {
+ if(result != null) {
+ try {
+ result.close();
+ } catch(Exception e) {
+ // fine, we tried
+ }
+ }
}
if (returnValue == null) {
throw noSuchAuthorityCode(CoordinateOperation.class, code);
@@ -2749,6 +2748,19 @@
return returnValue;
}
+ private boolean hasNext(ResultSet result) throws SQLException {
+ // this stuff works around a cross issue between h2 and hsql
+ // hsql does not have the isClosed method, h2 apparently caches
+ // and returns the ResultSet of a previous call even if the
+ // result was closed (crazy)
+ try {
+ return result.next();
+ } catch(SQLException e) {
+ // ugly I know, on trunk it looks better but here I don't have the necessary method
+ return false;
+ }
+ }
+
/**
* Creates operations from coordinate reference system codes.
* The returned set is ordered with the most accurate operations first.
|