简介
从GeoTools 14。一个新的JAI扩展API已经集成,这个新的API叫做 JAI-EXT.。
JAI-EXT是一个开源项目,它为图像处理提供了一个快速、高可伸缩性的API。这个API的主要特性是能够支持外部ROI对象和图像NoData的大部分处理操作。
编写此页是为了描述GeoTools内部的这个新API,演示它的使用,并解释使用它的最佳实践。
用法
JAI-EXT注册
想要使用JAI-EXT操作的项目需要首先注册它们。这可能是通过调用,在你的项目的顶部,以下一段代码:
static {
JAIExt.initJAIEXT();
}
这将在JAI OperationRegistry中注册所有JAI- ext操作,以便使用它们代替旧的JAI操作。
注意 需要指出的是,如果该方法被多次调用;它没有影响,因为它只是一个初始化方法。
上述更改可个别恢复:
JAIExt.registerJAIDescriptor("Warp") --> Replace the JAI-EXT "Warp" operation with the JAI one
JAIExt.registerJAIEXTDescriptor("Warp") --> Replace the JAI "Warp" operation with the JAI-EXT one
这些方法允许将与某个操作关联的操作描述符替换为来自JAI或JAI- ext的操作描述符。
注意 OperationDescriptor是一个类,描述用于执行JAI/JAI- ext操作的参数设置。
为了避免在替换了与JAI/JAI- ext操作相关的操作描述符后出现异常,用户应该注意如何启动操作:
- 使用ParameterBlock实例,它不提供与ParameterBlockJAI类相同的检查,这可能导致意外异常。这是一个例子
// Inputs
RenderedImage img; // Example image (256x256)
double[] scales = new double[]{2.0d};
double[] offsets = new double[]{1.0d};
// Input NoData, for example 128. It must be passed as a JAI-EXT "Range"
Range nodata = RangeFactory.create(128d, 128d);
// Input ROI
ROI roi = new ROIShape(new Rectangle(0, 0, 128, 128));
// Optional input RenderingHints
RenderingHints hints;
// Creation of the ParameterBlock
ParameterBlock pb = new ParameterBlock();
// Setting the parameters
pb.setSource(img, 0); // The source image.
pb.set(scales, 0); // The per-band constants to multiply by.
pb.set(offsets, 1); // The per-band offsets to be added.
pb.set(roi, 2); // ROI
pb.set(nodata, 3); // NoData range
// Calling the operation
RenderedOp result = JAI.create("Rescale", pb, hints);
- 如果存在,调用相关的GeoTools ImageWorker方法
// Same inputs as above
// Instantiation of the ImageWorker
ImageWorker w = new ImageWorker(img);
// Setting RenderingHints
w.setRenderingHints(img);
// Setting ROI and NoData
w.setROI(roi);
w.setNoData(nodata);
// Executing the operation
w.rescale(scales, offsets);
// Getting the result
RenderedOp result = w.getRenderedImage();
注意:
- JAI- ext项目的主要目标是完全取代所有JAI框架。在这个临时阶段,用户在启动时可能会注意到一些类似的错误消息
- 注册表文件第5行出错,描述符已经在注册模式“render”下注册名为“OrderedDither”
这些错误由JAI在较低级别报告,当JAI被完全替换时将被删除。
GeoTools注册
由于大部分地理工具操作在内部绑定到JAI操作,用户必须注意如何使用JAI- ext处理它们。
第一个建议是始终使用CoverageProcessor实例来获得GeoTools覆盖操作。最好是通过使用静态工厂方法CoverageProcessor. getinstance()来获得一个新的CoverageProcessor实例,因为这个方法允许缓存各种CoverageProcessor实例并在需要的时候重用它们。
替换操作描述符时,用户应该注意从所有的CoverageProcessor实例中删除现有的相关GeoTools操作,然后再次插入它。必须执行此程序,以避免使用已被替换的内部操作描述符的GeoTools操作;这种情况可能会导致错误的参数初始化,从而在覆盖处理期间导致异常。
过程如下所述。
CoverageProcessor.removeOperationFromProcessors("Warp"); // Removal of the operation from the processors
CoverageProcessor.updateProcessors(); // Update of all the processors with the new operation
最佳实践
下面是一段如何处理GridCoverage的NoData的简单代码。
// Creation of a new GridCoverage2D from a RenderedImage
RenderedImage img; // Example image (256x256)
// Coverage CRS
CoordinateReferenceSystem crs = CRS.decode("EPSG:4326");
// Coverage Envelope
Envelope envelope = new ReferencedEnvelope(-180, 180, -90, 90, crs);
// Coverage Properties
Map<String, Object> properties = new HashMap<String, Object>();
// NoData definition
double nodata = -9999;
// Wrapping NoData inside a container
NoDataContainer container = new NoDataContainer(nodata);
// Setting NoData as property
CoverageUtilities.setNoDataProperty(properties, container);
// Setting ROI as property
ROI roi = new ROIShape(new Rectangle(0, 0, 128, 128));
CoverageUtilities.setROIProperty(properties, roi);
// Creating the GridCoverage
GridCoverageFactory factory = new GridCoverageFactory();
GridCoverage2D coverage = factory.create("Test", img, envelope);
// Retrieving NoData from the GridCoverage
NoDataContainer newContainer = CoverageUtilities.getNoDataProperty(coverage);
// Retrieving ROI from GridCoverage
ROI newROI = CoverageUtilities.getROIProperty(coverage);
应该注意,NoData总是作为NoDataContainer实例返回。该类为以数组、单值或范围的形式访问NoData提供了有用的方法。下面的代码展示了如何在执行单个操作后更改NoData值。
// Getting CoverageProcessor
CoverageProcessor processor = CoverageProcessor.getInstance();
// Getting Scale operation
Operation scale = processor.getOperation("Scale");
// Getting scale parameters
ParameterValueGroup params = processor.getParameters();
params.parameter("Source0").setValue(coverage);
// Setting the Background. The first value will be taken as NoData if a NoData was already present in input
params.parameter("backgroundValues").setValue(new double[]{100});
// Executing the operation
GridCoverage2D result = (GridCoverage2D) processor.doOperation(params);
// Getting the new NoData value
NoDataContainer newNoDataContainer = CoverageUtilities.getNoDataProperty(result); // it should have 100 as NoData
注意:由于GTCrop操作已经转移到JAI- ext项目,用户应该注意用JAI替换JAI- ext会导致GTCrop提供的所有修复丢失。
网友评论