Skip to content

Commit

Permalink
GSIP-128 JAIEXT integration
Browse files Browse the repository at this point in the history
  • Loading branch information
n-lagomarsini committed Apr 7, 2015
1 parent edca4ca commit 6ae515c
Show file tree
Hide file tree
Showing 41 changed files with 520 additions and 259 deletions.
Binary file modified doc/en/user/source/webadmin/images/server_JAI.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions doc/en/user/source/webadmin/server/JAI.rst
Expand Up @@ -41,3 +41,10 @@ When supporting large images it is efficient to work on image subsets without lo
**Warp Native Acceleration**—Also for the Warp operation are provided both native and JAI implementations. If the checkbox is enabled, then the native operation is used for the warp operation.

*It is quite important to remember that faster encoders are not necessarily going to visibly improve performance, if data loading and processing/rendering are dominating the response time, choosing a better encoder will likely not provide the expected benefits.*

**JAI/JAI-EXT Setup**-This panel can be used for choosing which operations may be registered as *JAI* or *JAI-EXT* ones. Users have to select the operations to move and then, when clicking on *Save*, GeoServer internally will replace the *JAI/JAI-EXT* operations and the associated *GeoTools* ones. The main difference between *JAI* and *JAI-EXT* operations is the support for external **ROIs** and image **NoData**.

.. note:: More information about **JAI-EXT** may be found at the `JAI-EXT Project page <https://github.com/geosolutions-it/jai-ext>`_.

.. warning:: Users should take care that *JAI* native libraries are not supported by *JAI-EXT*, since *JAI-EXT* is a pure Java API.

@@ -1,10 +1,12 @@
/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
/* (c) 2014-2015 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wms.worldwind;

import it.geosolutions.jaiext.range.RangeFactory;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
Expand All @@ -26,7 +28,6 @@
import javax.media.jai.Interpolation;
import javax.media.jai.JAI;
import javax.media.jai.TiledImage;
import javax.media.jai.operator.FormatDescriptor;

import org.geoserver.catalog.MetadataMap;
import org.geoserver.data.util.CoverageUtils;
Expand All @@ -47,6 +48,7 @@
import org.geotools.coverage.grid.io.AbstractGridFormat;
import org.geotools.coverage.grid.io.GridCoverage2DReader;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.image.ImageWorker;
import org.geotools.referencing.CRS;
import org.geotools.resources.coverage.CoverageUtilities;
import org.geotools.util.logging.Logging;
Expand Down Expand Up @@ -197,18 +199,20 @@ public void formatImageOutputStream(RenderedImage image, OutputStream outStream,
{
bilEncoding = defaultDataType;
}

ImageWorker worker = new ImageWorker(transformedImage);
Double nod = inNoDataValues != null ? (outNoData != null ? outNoData : inNoDataValues[0]) : null;
worker.setnoData(nod != null ? RangeFactory.create(nod, nod) : null);
if((bilEncoding.equals("application/bil32")) && (dtype != DataBuffer.TYPE_FLOAT))
{
transformedImage = FormatDescriptor.create(transformedImage, DataBuffer.TYPE_FLOAT, null);
transformedImage = worker.format(DataBuffer.TYPE_FLOAT).getRenderedImage();
}
else if((bilEncoding.equals("application/bil16")) && (dtype != DataBuffer.TYPE_SHORT))
{
transformedImage = FormatDescriptor.create(transformedImage, DataBuffer.TYPE_SHORT, null);
transformedImage = worker.format(DataBuffer.TYPE_SHORT).getRenderedImage();
}
else if((bilEncoding.equals("application/bil8")) && (dtype != DataBuffer.TYPE_BYTE))
{
transformedImage = FormatDescriptor.create(transformedImage, DataBuffer.TYPE_BYTE, null);
transformedImage = worker.format(DataBuffer.TYPE_BYTE).getRenderedImage();
}

TiledImage tiled = new TiledImage(transformedImage,width,height);
Expand Down
@@ -1,4 +1,4 @@
/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
/* (c) 2014-2015 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
Expand All @@ -13,11 +13,7 @@
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.coverage.processing.CoverageProcessor;
import org.geotools.coverage.processing.operation.Crop;
import org.geotools.coverage.processing.operation.FilteredSubsample;
import org.geotools.coverage.processing.operation.Interpolate;
import org.geotools.coverage.processing.operation.Resample;
import org.geotools.coverage.processing.operation.Scale;
import org.geotools.coverage.processing.operation.SelectSampleDimension;
import org.geotools.factory.Hints;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.referencing.CRS;
Expand All @@ -41,34 +37,13 @@ public class BilWCSUtils extends WCSUtils {

public final static Hints LENIENT_HINT = new Hints(Hints.LENIENT_DATUM_SHIFT, Boolean.TRUE);

private final static SelectSampleDimension bandSelectFactory = new SelectSampleDimension();
private final static Crop cropFactory = new Crop();
private final static Interpolate interpolateFactory = new Interpolate();
private final static Scale scaleFactory = new Scale();
private final static FilteredSubsample filteredSubsampleFactory = new FilteredSubsample();
private final static Resample resampleFactory = new Resample();
// ///////////////////////////////////////////////////////////////////
//
// Static Processors
//
// ///////////////////////////////////////////////////////////////////
private static final CoverageProcessor processor = CoverageProcessor.getInstance();

static {
// ///////////////////////////////////////////////////////////////////
//
// Static Processors
//
// ///////////////////////////////////////////////////////////////////
final CoverageProcessor processor = new CoverageProcessor();
bandSelectParams = processor.getOperation("SelectSampleDimension").getParameters();
cropParams = processor.getOperation("CoverageCrop").getParameters();
interpolateParams = processor.getOperation("Interpolate").getParameters();
scaleParams = processor.getOperation("Scale").getParameters();
resampleParams = processor.getOperation("Resample").getParameters();
filteredSubsampleParams = processor.getOperation("FilteredSubsample").getParameters();
}

private final static ParameterValueGroup bandSelectParams;
private final static ParameterValueGroup cropParams;
private final static ParameterValueGroup interpolateParams;
private final static ParameterValueGroup resampleParams;
private final static ParameterValueGroup scaleParams;
private final static ParameterValueGroup filteredSubsampleParams;
private final static Hints hints = new Hints(new HashMap(5));

static {
Expand Down Expand Up @@ -106,13 +81,13 @@ public static GridCoverage2D reproject(GridCoverage2D coverage,
* Operations.DEFAULT.resample( coverage, targetCRS, null,
* Interpolation.getInstance(Interpolation.INTERP_NEAREST))
*/
final ParameterValueGroup param = (ParameterValueGroup) resampleParams.clone();
final ParameterValueGroup param = (ParameterValueGroup) processor.getOperation("Resample").getParameters();
param.parameter("Source").setValue(coverage);
param.parameter("CoordinateReferenceSystem").setValue(targetCRS);
param.parameter("GridGeometry").setValue(null);
param.parameter("InterpolationType").setValue(interpolation);

coverage = (GridCoverage2D) resampleFactory.doOperation(param, hints);
coverage = (GridCoverage2D) ((Resample)processor.getOperation("Resample")).doOperation(param, hints);
}

return coverage;
Expand Down Expand Up @@ -154,14 +129,14 @@ public static GridCoverage2D scale(final GridCoverage2D coverage, final GridEnve
* Operations.DEFAULT.resample( coverage, sourceCRS, scaledGridGeometry,
* Interpolation.getInstance(Interpolation.INTERP_NEAREST));
*/
final ParameterValueGroup param = (ParameterValueGroup) resampleParams.clone();
final ParameterValueGroup param = (ParameterValueGroup) processor.getOperation("Resample").getParameters();
param.parameter("Source").setValue(coverage);
param.parameter("CoordinateReferenceSystem").setValue(sourceCRS);
param.parameter("GridGeometry").setValue(scaledGridGeometry);
param.parameter("InterpolationType")
.setValue(Interpolation.getInstance(Interpolation.INTERP_NEAREST));

final GridCoverage2D scaledGridCoverage = (GridCoverage2D) resampleFactory.doOperation(param,
final GridCoverage2D scaledGridCoverage = (GridCoverage2D) ((Resample)processor.getOperation("Resample")).doOperation(param,
hints);

return scaledGridCoverage;
Expand Down Expand Up @@ -211,12 +186,12 @@ public static GridCoverage2D crop(final Coverage coverage,
// intersectionEnvelope, gridCoverage);

/* Operations.DEFAULT.crop(coverage, intersectionEnvelope) */
final ParameterValueGroup param = (ParameterValueGroup) cropParams.clone();
final ParameterValueGroup param = (ParameterValueGroup) processor.getOperation("CoverageCrop").getParameters();
param.parameter("Source").setValue(coverage);
param.parameter("Envelope").setValue(intersectionEnvelope);
//param.parameter("ConserveEnvelope").setValue(conserveEnvelope);

croppedGridCoverage = (GridCoverage2D) cropFactory.doOperation(param, hints);
croppedGridCoverage = (GridCoverage2D) ((Crop)processor.getOperation("CoverageCrop")).doOperation(param, hints);
} else {
croppedGridCoverage = (GridCoverage2D) coverage;
}
Expand Down
@@ -1,4 +1,4 @@
/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
/* (c) 2014-2015 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
Expand Down Expand Up @@ -31,7 +31,6 @@
import javax.imageio.stream.ImageOutputStream;
import javax.media.jai.ImageLayout;
import javax.media.jai.JAI;
import javax.media.jai.operator.FormatDescriptor;

import org.geotools.image.ImageWorker;
import org.geotools.resources.image.ImageUtilities;
Expand Down Expand Up @@ -169,7 +168,9 @@ private void removeAlpha(int requestedBands) {
layout.setSampleModel(sm);

// Forcing the output format to remove the alpha Band
image = FormatDescriptor.create(image, DataBuffer.TYPE_BYTE, hints);
ImageWorker worker = new ImageWorker(image);
worker.setRenderingHints(hints);
image = worker.format(DataBuffer.TYPE_BYTE).getRenderedImage();
}

}
@@ -1,4 +1,4 @@
/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
/* (c) 2014-2015 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
Expand Down Expand Up @@ -251,8 +251,9 @@ public Map<String, Object> execute(
}

GridCoverage2D addLocationProperty(GridCoverage2D coverage, File warpedFile) {
Map <String, String> properties = new HashMap<String,String>();
Map properties = new HashMap();
properties.put(GridCoverage2DReader.FILE_SOURCE_PROPERTY, warpedFile.getAbsolutePath());
properties.putAll(coverage.getProperties());

return new GridCoverageFactory().create(coverage.getName(), coverage.getRenderedImage(),
coverage.getGridGeometry(), coverage.getSampleDimensions(), null, properties);
Expand Down
@@ -1,4 +1,4 @@
/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
/* (c) 2014-2015 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
Expand Down Expand Up @@ -97,7 +97,7 @@ public void testCrop() throws Exception {
double[] valueInside = (double[]) gc.evaluate(new DirectPosition2D(145.55, -42));
assertEquals(615.0, valueInside[0]);
double[] valueOutside = (double[]) gc.evaluate(new DirectPosition2D(145.57, -41.9));
// this should really be NaN...
assertEquals(0.0, valueOutside[0]);
// this should really be NoData
assertEquals(-9999 & 0xFFFF, (int)valueOutside[0]);
}
}
@@ -1,4 +1,4 @@
/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
/* (c) 2014-2015 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
Expand All @@ -13,11 +13,11 @@
import org.geoserver.data.test.MockData;
import org.geoserver.data.test.SystemTestData;
import org.geoserver.wps.WPSTestSupport;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.gce.arcgrid.ArcGridFormat;
import org.geotools.geometry.DirectPosition2D;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.junit.Test;
import org.opengis.coverage.grid.GridCoverage;

import com.mockrunner.mock.web.MockHttpServletResponse;
import com.vividsolutions.jts.geom.Envelope;
Expand Down Expand Up @@ -87,12 +87,14 @@ public void testAddOperation() throws Exception {
InputStream is = getBinaryInputStream(response);

ArcGridFormat format = new ArcGridFormat();
GridCoverage gc = format.getReader(is).read(null);
GridCoverage2D gc = format.getReader(is).read(null);

assertTrue(new Envelope(144.9, 146.1, -40.9, -43.1).contains(new ReferencedEnvelope(gc.getEnvelope())));

addToSameCoverageValue = (double[]) gc.evaluate(new DirectPosition2D(145.9584, -41.6587));
assertEquals(1978.0, addToSameCoverageValue[0], DELTA);

gc.dispose(true);
}

@Test
Expand Down Expand Up @@ -146,12 +148,14 @@ public void testMultiplyOperation() throws Exception {
InputStream is = getBinaryInputStream(response);

ArcGridFormat format = new ArcGridFormat();
GridCoverage gc = format.getReader(is).read(null);
GridCoverage2D gc = format.getReader(is).read(null);

assertTrue(new Envelope(144.9, 146.1, -40.9, -43.1).contains(new ReferencedEnvelope(gc.getEnvelope())));

multiplyForSameCoverageValue = (double[]) gc.evaluate(new DirectPosition2D(145.9584, -41.6587));
assertEquals(978121.0, multiplyForSameCoverageValue[0], DELTA);

gc.dispose(true);
}

@Test
Expand Down
@@ -1,4 +1,4 @@
/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
/* (c) 2014-2015 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
Expand All @@ -15,11 +15,11 @@
import org.geoserver.data.test.SystemTestData;
import org.geoserver.platform.GeoServerExtensions;
import org.geoserver.wps.WPSTestSupport;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.gce.arcgrid.ArcGridFormat;
import org.geotools.geometry.DirectPosition2D;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.junit.Test;
import org.opengis.coverage.grid.GridCoverage;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
Expand Down Expand Up @@ -73,15 +73,17 @@ public void testCrop() throws Exception {
InputStream is = getBinaryInputStream(response);

ArcGridFormat format = new ArcGridFormat();
GridCoverage gc = format.getReader(is).read(null);
GridCoverage2D gc = format.getReader(is).read(null);

assertTrue(new Envelope(-145.4, 145.6, -41.8, -42.1).contains(new ReferencedEnvelope(gc.getEnvelope())));

double[] valueInside = (double[]) gc.evaluate(new DirectPosition2D(145.55, -42));
assertEquals(615.0, valueInside[0]);
double[] valueOutside = (double[]) gc.evaluate(new DirectPosition2D(145.57, -41.9));
// this should really be NaN...
assertEquals(0.0, valueOutside[0]);
// this should really be NoData... (-9999 & 0xFFFF)
assertEquals(55537.0, valueOutside[0]);

gc.dispose(true);
}

@Test
Expand Down
@@ -1,4 +1,4 @@
/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
/* (c) 2014-2015 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
Expand All @@ -13,6 +13,7 @@
import org.geoserver.data.test.MockData;
import org.geoserver.data.test.SystemTestData;
import org.geoserver.wps.WPSTestSupport;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.gce.arcgrid.ArcGridFormat;
import org.junit.Test;
import org.opengis.coverage.grid.GridCoverage;
Expand Down Expand Up @@ -94,7 +95,7 @@ public void testScale() throws Exception {
ArcGridFormat format = new ArcGridFormat();
GridCoverage gc = format.getReader(is).read(null);

GridCoverage original = getCatalog().getCoverageByName(getLayerId(MockData.TASMANIA_DEM)).getGridCoverage(null, null);
GridCoverage2D original = (GridCoverage2D) getCatalog().getCoverageByName(getLayerId(MockData.TASMANIA_DEM)).getGridCoverage(null, null);
scheduleForDisposal(original);

// check the envelope did not change
Expand Down
@@ -1,4 +1,4 @@
/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
/* (c) 2014-2015 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
Expand All @@ -16,15 +16,14 @@
import java.io.OutputStream;

import javax.media.jai.PlanarImage;
import javax.media.jai.RenderedOp;

import org.geoserver.gwc.GWC;
import org.geoserver.ows.Response;
import org.geoserver.wms.WMSMapContent;
import org.geoserver.wms.map.RenderedImageMap;
import org.geoserver.wms.map.RenderedImageMapResponse;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.image.crop.GTCropDescriptor;
import org.geotools.image.ImageWorker;
import org.geotools.resources.i18n.ErrorKeys;
import org.geotools.resources.i18n.Errors;
import org.geowebcache.grid.BoundingBox;
Expand Down Expand Up @@ -160,11 +159,10 @@ public RenderedImage createTile(final int x, final int y, final int tileWidth,
case 0:
// do a crop, and then turn it into a buffered image so that we can release
// the image chain
RenderedOp cropped = GTCropDescriptor
.create(metaTileImage, Float.valueOf(x), Float.valueOf(y),
Float.valueOf(tileWidth), Float.valueOf(tileHeight), NO_CACHE);
tile = cropped.getAsBufferedImage();
disposeLater(cropped);
ImageWorker w = new ImageWorker(metaTileImage);
w.crop(Float.valueOf(x), Float.valueOf(y), Float.valueOf(tileWidth), Float.valueOf(tileHeight));
tile = w.getBufferedImage();
disposeLater(w.getRenderedImage());
break;
case 1:
final PlanarImage pImage = (PlanarImage) metaTileImage;
Expand Down

0 comments on commit 6ae515c

Please sign in to comment.