Merge "Issue #1314 removed common.spatial plugin" into development

Former-commit-id: 823cb0e07793ec5baa1863088634a312364b3d8b
This commit is contained in:
Nate Jensen 2013-11-11 08:48:44 -06:00 committed by Gerrit Code Review
commit 0dbc31b756
23 changed files with 232 additions and 2213 deletions

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.uf.common.spatial</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -1,8 +0,0 @@
#Thu Dec 02 10:55:26 CST 2010
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

View file

@ -1,16 +0,0 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: com.raytheon.uf.common.spatial
Bundle-SymbolicName: com.raytheon.uf.common.spatial
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: RAYTHEON
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Export-Package: com.raytheon.uf.common.spatial.reprojection
Require-Bundle: org.apache.commons.lang;bundle-version="2.3.0",
org.geotools;bundle-version="2.6.4",
com.raytheon.uf.common.geospatial;bundle-version="1.12.1174",
com.raytheon.uf.common.dataplugin;bundle-version="1.12.1174",
com.raytheon.uf.common.datastorage;bundle-version="1.12.1174",
com.raytheon.uf.common.serialization;bundle-version="1.12.1174"
Import-Package: org.apache.commons.logging

View file

@ -1,4 +0,0 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

View file

@ -1,150 +0,0 @@
/*
* The following software products were developed by Raytheon:
*
* ADE (AWIPS Development Environment) software
* CAVE (Common AWIPS Visualization Environment) software
* EDEX (Environmental Data Exchange) software
* uFrame (Universal Framework) software
*
* Copyright (c) 2010 Raytheon Co.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/epl-v10.php
*
*
* Contractor Name: Raytheon Company
* Contractor Address:
* 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 15, 2011 bclement Initial creation
*
*/
package com.raytheon.uf.common.spatial.reprojection;
import java.awt.image.DataBuffer;
import java.awt.image.WritableRaster;
import javax.media.jai.RasterFactory;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.GridCoverageFactory;
import org.geotools.geometry.jts.ReferencedEnvelope;
import com.raytheon.uf.common.datastorage.Request;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
/**
*
* @author bclement
* @version 1.0
*/
public abstract class AbstractDataReprojector<T extends IDataRecord> {
public static class RequestWrapper {
public Request req;
public ReferencedEnvelope env;
}
/**
* Copy data record into geotools grid coverage object
*
* @param dataRecord
* datset
* @param env
* geographics bounds for dataset
* @return
* @throws Exception
*/
protected abstract GridCoverage2D getGridCoverage(IDataRecord dataRecord,
ReferencedEnvelope env) throws Exception;
/**
* Copy data record into geotools grid coverage object
*
* @param dataRecord
* datset
* @param env
* geographics bounds for dataset
* @return
* @throws Exception
*/
protected abstract GridCoverage2D getMaskCoverage(IDataRecord dataRecord,
ReferencedEnvelope env) throws Exception;
/**
* Extract data from geotools coverage object into data record object
*
* @param coverage
* @return
*/
protected abstract T extractData(GridCoverage2D coverage);
/**
* Extract data from geotools coverage object into data record object with a
* mask for covering the non-data area.
*
* @param coverage
* @param maskCoverage
* @return
*/
protected abstract T extractData(GridCoverage2D coverage,
GridCoverage2D maskCoverage);
/**
* Apply slab request to data record, returning result in a new data record
* object.
*
* @param dataRecord
* @param req
* @return
*/
protected abstract T getDataSlice(IDataRecord dataRecord, Request req);
/**
* @param dataRecord
* @return true if this object can operate on native type of data record
*/
protected abstract boolean compatible(IDataRecord dataRecord);
/**
* Apply point request to data record, returning result in a new data record
* object.
*
* @param record
* @param req
* @return
*/
protected abstract IDataRecord getDataPoints(IDataRecord record, Request req);
/**
* Construct a new geotools grid coverage object using data buffer
*
* @param name
* name of coverage
* @param data
* raw data
* @param width
* @param height
* @param env
* geographic bounds of coverage
* @return
* @throws Exception
*/
public static GridCoverage2D constructGridCoverage(String name,
DataBuffer data, int width, int height, ReferencedEnvelope env)
throws Exception {
WritableRaster raster = RasterFactory.createBandedRaster(data, width,
height, width, new int[] { 0 }, new int[] { 0 }, null);
return new GridCoverageFactory().create(name, raster, env);
}
}

View file

@ -1,238 +0,0 @@
/*
* The following software products were developed by Raytheon:
*
* ADE (AWIPS Development Environment) software
* CAVE (Common AWIPS Visualization Environment) software
* EDEX (Environmental Data Exchange) software
* uFrame (Universal Framework) software
*
* Copyright (c) 2010 Raytheon Co.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/epl-v10.php
*
*
* Contractor Name: Raytheon Company
* Contractor Address:
* 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 18, 2011 bclement Initial creation
*
*/
package com.raytheon.uf.common.spatial.reprojection;
import java.awt.Point;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.util.Arrays;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.raytheon.uf.common.datastorage.Request;
import com.raytheon.uf.common.datastorage.records.ByteDataRecord;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
/**
*
* @author bclement
* @version 1.0
*/
public class ByteDataReprojector extends
AbstractDataReprojector<ByteDataRecord> {
protected byte fill = 0;
protected byte dataMaskValue = -1;
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#getGridCoverage
* (com.raytheon.uf.common.datastorage.records.IDataRecord,
* org.opengis.referencing.crs.CoordinateReferenceSystem,
* org.opengis.geometry.Envelope)
*/
@Override
protected GridCoverage2D getGridCoverage(IDataRecord record,
ReferencedEnvelope env)
throws Exception {
ByteDataRecord dataRecord = (ByteDataRecord) record;
byte[] data = dataRecord.getByteData();
DataBufferByte buff = new DataBufferByte(data, data.length);
int x = (int) dataRecord.getSizes()[0];
int y = (int) dataRecord.getSizes()[1];
CoordinateReferenceSystem crs = env.getCoordinateReferenceSystem();
return constructGridCoverage(crs.getName() + " Grid", buff, x, y, env);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#getMaskCoverage
* (com.raytheon.uf.common.datastorage.records.IDataRecord,
* org.opengis.referencing.crs.CoordinateReferenceSystem,
* org.opengis.geometry.Envelope)
*/
@Override
protected GridCoverage2D getMaskCoverage(IDataRecord record,
ReferencedEnvelope env) throws Exception {
int x = (int) record.getSizes()[0];
int y = (int) record.getSizes()[1];
byte[] mask = new byte[x * y];
Arrays.fill(mask, dataMaskValue);
DataBufferByte buff = new DataBufferByte(mask, mask.length);
CoordinateReferenceSystem crs = env.getCoordinateReferenceSystem();
return constructGridCoverage(crs.getName() + " Grid", buff, x, y, env);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#extractData(org
* .geotools.coverage.grid.GridCoverage2D)
*/
@Override
protected ByteDataRecord extractData(GridCoverage2D coverage) {
RenderedImage image = coverage.getRenderedImage();
Raster raster;
if (image.getNumXTiles() == 1 && image.getNumYTiles() == 1) {
// we can directly access data
raster = image.getTile(0, 0);
} else {
// need to copy data out
raster = image.getData();
}
DataBufferByte dataBuffer = (DataBufferByte) raster.getDataBuffer();
byte[] data = dataBuffer.getData();
int height = raster.getHeight();
int width = raster.getWidth();
return new ByteDataRecord("", "", data, 2, new long[] { width, height });
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#extractData(org
* .geotools.coverage.grid.GridCoverage2D,
* org.geotools.coverage.grid.GridCoverage2D)
*/
@Override
protected ByteDataRecord extractData(GridCoverage2D coverage,
GridCoverage2D maskCoverage) {
RenderedImage image = coverage.getRenderedImage();
Raster raster;
if (image.getNumXTiles() == 1 && image.getNumYTiles() == 1) {
// we can directly access data
raster = image.getTile(0, 0);
} else {
// need to copy data out
raster = image.getData();
}
DataBufferByte dataBuffer = (DataBufferByte) raster.getDataBuffer();
byte[] data = dataBuffer.getData();
// Extract mask
image = maskCoverage.getRenderedImage();
if (image.getNumXTiles() == 1 && image.getNumYTiles() == 1) {
// we can directly access data
raster = image.getTile(0, 0);
} else {
// need to copy data out
raster = image.getData();
}
dataBuffer = (DataBufferByte) raster.getDataBuffer();
byte[] mask = dataBuffer.getData();
if (mask.length == data.length) {
for (int i = 0; i < data.length; ++i) {
if (mask[i] != dataMaskValue) {
data[i] = fill;
}
}
}
int height = raster.getHeight();
int width = raster.getWidth();
return new ByteDataRecord("", "", data, 2, new long[] { width, height });
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#getDataSlice(com
* .raytheon.uf.common.datastorage.records.IDataRecord,
* com.raytheon.uf.common.datastorage.Request)
*/
@Override
protected ByteDataRecord getDataSlice(IDataRecord record, Request req) {
ByteDataRecord dataRecord = (ByteDataRecord) record;
int[] max = req.getMaxIndexForSlab();
int[] min = req.getMinIndexForSlab();
int toWidth = max[0] - min[0];
int toHeight = max[1] - min[1];
byte[] from = dataRecord.getByteData();
int fromWidth = (int) dataRecord.getSizes()[0];
byte[] to = new byte[toWidth * toHeight];
for (int fromY = min[1], toY = 0; fromY < max[1]; ++fromY, ++toY) {
int toRow = toY * toWidth;
int fromRow = fromY * fromWidth;
for (int fromX = min[0], toX = 0; fromX < max[0]; ++fromX, ++toX) {
to[toRow + toX] = from[fromRow + fromX];
}
}
long[] sizes = { toWidth, toHeight };
return new ByteDataRecord("", "", to, 2, sizes);
}
public byte getFill() {
return fill;
}
public void setFill(byte fill) {
this.fill = fill;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.AbstractDataReprojector#compatible
* (com.raytheon.uf.common.datastorage.records.IDataRecord)
*/
@Override
protected boolean compatible(IDataRecord dataRecord) {
return dataRecord instanceof ByteDataRecord;
}
@Override
protected IDataRecord getDataPoints(IDataRecord record, Request req) {
ByteDataRecord dataRecord = (ByteDataRecord) record;
byte[] from = dataRecord.getByteData();
int fromWidth = (int) dataRecord.getSizes()[0];
Point[] points = req.getPoints();
byte[] to = new byte[points.length];
for (int i = 0; i < to.length; ++i) {
Point p = points[i];
to[i] = from[p.y * fromWidth + p.x];
}
return new ByteDataRecord("", "", to, 1, new long[] { to.length });
}
}

View file

@ -1,632 +0,0 @@
/*
* The following software products were developed by Raytheon:
*
* ADE (AWIPS Development Environment) software
* CAVE (Common AWIPS Visualization Environment) software
* EDEX (Environmental Data Exchange) software
* uFrame (Universal Framework) software
*
* Copyright (c) 2010 Raytheon Co.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/epl-v10.php
*
*
* Contractor Name: Raytheon Company
* Contractor Address:
* 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 18, 2011 bclement Initial creation
*
*/
package com.raytheon.uf.common.spatial.reprojection;
import java.awt.Point;
import java.io.FileNotFoundException;
import java.util.Iterator;
import java.util.Set;
import javax.media.jai.Interpolation;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geotools.coverage.grid.GeneralGridEnvelope;
import org.geotools.coverage.grid.GridCoordinates2D;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.coverage.grid.ViewType;
import org.geotools.coverage.processing.Operations;
import org.geotools.geometry.DirectPosition2D;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.CRS;
import org.opengis.geometry.DirectPosition;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.metadata.spatial.PixelOrientation;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.ReferenceIdentifier;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform2D;
import org.opengis.referencing.operation.TransformException;
import com.raytheon.uf.common.dataplugin.PluginException;
import com.raytheon.uf.common.datastorage.IDataStore;
import com.raytheon.uf.common.datastorage.Request;
import com.raytheon.uf.common.datastorage.StorageException;
import com.raytheon.uf.common.datastorage.records.ByteDataRecord;
import com.raytheon.uf.common.datastorage.records.FloatDataRecord;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.datastorage.records.IntegerDataRecord;
import com.raytheon.uf.common.datastorage.records.ShortDataRecord;
import com.raytheon.uf.common.geospatial.ISpatialObject;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.spatial.reprojection.AbstractDataReprojector.RequestWrapper;
import com.raytheon.uf.common.spatial.reprojection.KeyLocker.KeyLock;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
/**
*
* @author bclement
* @version 1.0
*/
public class DataReprojector {
protected IDataStore dataStore;
protected String dataSetBase = "Data-";
protected String dataSet = "Data";
private AbstractDataReprojector<? extends IDataRecord> _typeProjector;
protected static Log log = LogFactory.getLog(DataReprojector.class);
protected static KeyLocker locker = new KeyLocker();
public DataReprojector(IDataStore dataStore) {
this.dataStore = dataStore;
}
/**
* @param group
* name of the datastore group that contains requested dataset
* @param spatial
* spatial object tied to requested dataset
* @param nativeEnv
* native bounds of dataset
* @param crs
* desired crs of returned data
* @param coords
* coordinates of requested data in requested crs
* @return null if any of the coordinates are out of the bounds of the grid
* geometry
* @throws Exception
*/
public IDataRecord getProjectedPoints(String group, ISpatialObject spatial,
ReferencedEnvelope nativeEnv, CoordinateReferenceSystem crs,
Coordinate[] coords) throws Exception {
// get envelope in requested projection
ReferencedEnvelope targetEnv = nativeEnv.transform(crs, true);
// get target grid geometry
GridGeometry2D geom = getGridGeometry(targetEnv, spatial.getNx(),
spatial.getNy());
Point[] points = new Point[coords.length];
for (int i = 0; i < points.length; ++i) {
Coordinate coord = coords[i];
GridCoordinates2D point = getGridPoint(geom, coord);
int nx = spatial.getNx();
int ny = spatial.getNy();
// coordinate was out of bounds, bail
if (point.x < 0 || point.x > nx || point.y < 0 || point.y > ny) {
return null;
}
// need to repackage point due to pypies not knowing about
// gridcoordinates2d
points[i] = new Point(point);
}
String reprojectedDataset = buildDatasetName(crs);
Request req = Request.buildPointRequest(points);
return getDataRecordWithReproject(group, reprojectedDataset, spatial,
crs, req);
}
/**
* @param group
* name of the datastore group that contains requested dataset
* @param reprojectedDataset
* dataset name for reprojected data
* @param spatial
* spatial object tied to requested dataset
* @param crs
* desired crs of returned data
* @param req
* datastore request object
* @return
* @throws Exception
*/
protected IDataRecord getDataRecordWithReproject(String group,
String reprojectedDataset, ISpatialObject spatial,
CoordinateReferenceSystem crs, Request req) throws Exception {
IDataRecord dataRecord;
if (CRS.equalsIgnoreMetadata(crs, spatial.getCrs())) {
// original dataset, no reproject
reprojectedDataset = dataSet;
}
// check if data has already been reprojected
if (!datasetExists(group, reprojectedDataset)) {
// it hasn't lock and reproject
dataRecord = reprojectLocked(group, reprojectedDataset, spatial,
crs, req);
} else {
// it has, just request the data
dataRecord = getDataRecord(group, reprojectedDataset, req);
}
return dataRecord;
}
/**
* @param group
* name of the datastore group that contains requested dataset
* @param reprojectedDataset
* dataset name for reprojected data
* @param spatial
* spatial object tied to requested dataset
* @param crs
* desired crs of returned data
* @param req
* datastore request object
* @return
* @throws Exception
*/
protected IDataRecord reprojectLocked(String group,
String reprojectedDataset, ISpatialObject spatial,
CoordinateReferenceSystem crs, Request req) throws Exception {
KeyLock lock = null;
IDataRecord dataRecord;
try {
// get reproject lock
lock = locker.getLock(group + reprojectedDataset);
lock.lock();
// recheck that dataset still doesn't exist
if (!datasetExists(group, reprojectedDataset)) {
// still not there, reproject
dataRecord = reprojectAndStore(spatial, group, crs, req);
} else {
// another thread created it, just grab it
dataRecord = getDataRecord(group, reprojectedDataset, req);
}
lock.unlock();
return dataRecord;
} finally {
if (lock != null) {
lock.release();
}
}
}
/**
* @param group
* @param dataset
* @return true if dataset exists in datastore
* @throws FileNotFoundException
* @throws StorageException
*/
protected boolean datasetExists(String group, String dataset)
throws FileNotFoundException, StorageException {
String[] datasets = dataStore.getDatasets(group);
return ArrayUtils.contains(datasets, dataset);
}
/**
* @param geom
* Grid geometry
* @param coord
* desired geographic coordinate
* @return grid point for coordinate
* @throws PluginException
*/
public static GridCoordinates2D getGridPoint(GridGeometry2D geom,
Coordinate coord) throws PluginException {
DirectPosition src = new DirectPosition2D(coord.x, coord.y);
DirectPosition inGrid = new DirectPosition2D();
try {
MathTransform2D crsToGrid2D = geom
.getCRSToGrid2D(PixelOrientation.UPPER_LEFT);
crsToGrid2D.transform(src, inGrid);
} catch (Exception e) {
throw new PluginException("Unable to get grid point for geometry",
e);
}
// floor of grid points should be upper left of pixel
int x = (int) Math.floor(inGrid.getOrdinate(0));
int y = (int) Math.floor(inGrid.getOrdinate(1));
GridCoordinates2D rval = new GridCoordinates2D(x, y);
return rval;
}
/**
* @param group
* name of the datastore group that contains requested dataset
* @param spatial
* spatial object tied to requested dataset
* @param nativeEnv
* native bounds of dataset
* @param targetEnv
* bounds of requested data
* @return null if target envelope is out of bounds for dataset
* @throws Exception
*/
public GridCoverage2D getReprojectedCoverage(String group,
ISpatialObject spatial, ReferencedEnvelope nativeEnv,
ReferencedEnvelope targetEnv)
throws Exception {
ReferencedDataRecord rep = getReprojected(group, spatial, nativeEnv,
targetEnv);
if (rep == null) {
return null;
}
ReferencedEnvelope re = rep.getEnvelope();
IDataRecord record = rep.getRecord();
return getTypeProjector(record).getGridCoverage(rep.getRecord(), re);
}
/**
* @param group
* name of the datastore group that contains requested dataset
* @param spatial
* spatial object tied to requested dataset
* @param nativeEnvelope
* native bounds of dataset
* @param targetEnvelope
* bounds of requested data
* @return null if target envelope is out of bounds for dataset
* @throws Exception
*/
public ReferencedDataRecord getReprojected(String group,
ISpatialObject spatial, ReferencedEnvelope nativeEnvelope,
ReferencedEnvelope targetEnvelope)
throws Exception {
RequestWrapper req = getRequest(spatial, nativeEnvelope, targetEnvelope);
if (req == null) {
return null;
}
CoordinateReferenceSystem targetCrs = targetEnvelope
.getCoordinateReferenceSystem();
String reprojectedDataset = buildDatasetName(targetCrs);
IDataRecord dataRecord = getDataRecordWithReproject(group,
reprojectedDataset, spatial, targetCrs, req.req);
return new ReferencedDataRecord(dataRecord, req.env);
}
/**
* @param group
* name of the datastore group that contains requested dataset
* @param targetDataset
* dataset name for requested data
* @param req
* datastore request object
* @return
* @throws Exception
*/
protected IDataRecord getDataRecord(String group, String targetDataset,
Request req) throws Exception {
IDataRecord rval = dataStore.retrieve(group, targetDataset, req);
return rval;
}
/**
* Get a projector that is compatible with record
*
* @param record
* @return
* @throws Exception
*/
protected AbstractDataReprojector<? extends IDataRecord> getTypeProjector(
IDataRecord record) throws Exception {
if (_typeProjector == null || !_typeProjector.compatible(record)) {
if (record instanceof ByteDataRecord) {
_typeProjector = new ByteDataReprojector();
} else if (record instanceof FloatDataRecord) {
_typeProjector = new FloatDataReprojector();
} else if (record instanceof ShortDataRecord) {
_typeProjector = new ShortDataReprojector();
} else if (record instanceof IntegerDataRecord) {
_typeProjector = new IntDataReprojector();
} else {
throw new Exception("Unsupported data store type");
}
}
return _typeProjector;
}
/**
* Gets the entire coverage from the store and reprojects it. Reprojected
* coverage is then stored under a name derived from the projected crs.
*
* @param spatial
* spatial object tied to requested dataset
* @param group
* name of the datastore group that contains requested dataset
* @param targetCRS
* desired crs of returned data
* @param req
* datastore request object
* @return datarecord as per the request object
* @throws Exception
*/
protected IDataRecord reprojectAndStore(ISpatialObject spatial,
String group, CoordinateReferenceSystem targetCRS, Request req)
throws Exception {
GridGeometry2D geom = MapUtil.getGridGeometry(spatial);
IDataRecord original = getDataRecord(group, dataSet, Request.ALL);
ReferencedEnvelope env = new ReferencedEnvelope(geom.getEnvelope());
AbstractDataReprojector<? extends IDataRecord> typeProjector = getTypeProjector(original);
GridCoverage2D cov = typeProjector.getGridCoverage(original, env);
GridCoverage2D reprojected = MapUtil.reprojectCoverage(cov, targetCRS);
IDataRecord rval;
if (typeProjector instanceof FloatDataReprojector) {
// TODO So far, the problem that this fixes has only appeared with
// float data. If it happens with other data we can change this.
GridCoverage2D maskCov = typeProjector.getMaskCoverage(original,
env);
GridCoverage2D reprojectedMask = (GridCoverage2D) Operations.DEFAULT
.resample(maskCov.view(ViewType.GEOPHYSICS), targetCRS,
null, Interpolation
.getInstance(Interpolation.INTERP_NEAREST));
rval = typeProjector.extractData(reprojected, reprojectedMask);
} else {
rval = typeProjector.extractData(reprojected);
}
rval.setGroup(group);
rval.setName(buildDatasetName(targetCRS));
dataStore.addDataRecord(rval);
dataStore.store();
return getDataPerReq(rval, req);
}
/**
* @param record
* data record containing full coverage
* @param req
* datastore request object
* @return result of applying request object to data record
* @throws Exception
*/
protected IDataRecord getDataPerReq(IDataRecord record, Request req)
throws Exception {
AbstractDataReprojector<? extends IDataRecord> typeProjector = getTypeProjector(record);
IDataRecord rval;
switch (req.getType()) {
case ALL:
rval = record;
break;
case POINT:
rval = typeProjector.getDataPoints(record, req);
break;
case SLAB:
rval = typeProjector.getDataSlice(record, req);
break;
case XLINE:
case YLINE:
default:
throw new Exception("Data reprojector " + req.getType()
+ " not implemented");
}
return rval;
}
/**
* @param env
* geographic bounds of data
* @param nx
* length of x axis
* @param ny
* length of y axis
* @return
*/
public static GridGeometry2D getGridGeometry(ReferencedEnvelope env,
int nx, int ny) {
// TODO cache
GridGeometry2D mapGeom = null;
mapGeom = new GridGeometry2D(new GeneralGridEnvelope(
new int[] { 0, 0 }, new int[] { nx, ny }, false), env);
return mapGeom;
}
/**
* Build up slice request for reprojected dataset
*
* @param record
* @param crs
* @param targetEnvelope
* bbox in crs
* @return null if envelope is outside of data bounds
* @throws TransformException
* @throws MismatchedDimensionException
* @throws FactoryException
*/
public static RequestWrapper getRequest(ISpatialObject spatial,
ReferencedEnvelope nativeEnv, ReferencedEnvelope targetEnvelope)
throws MismatchedDimensionException,
TransformException, FactoryException {
RequestWrapper rval = null;
CoordinateReferenceSystem targetCrs = targetEnvelope
.getCoordinateReferenceSystem();
// get full bounds of reprojected dataset
ReferencedEnvelope dataEnv = nativeEnv.transform(targetCrs, true);
if (!dataEnv.intersects((Envelope) targetEnvelope)) {
// request and data envelopes are disjoint, return null
return null;
}
// get grid geometry for reprojected dataset
GridGeometry2D geom = getGridGeometry(dataEnv, spatial.getNx(),
spatial.getNy());
int[] dims = { spatial.getNx(), spatial.getNy() };
if (dataEnv.contains((Envelope) targetEnvelope)) {
// requested slice is entirely inside data bounds
// build slice based on requested bounds
rval = getSubSlice(geom, targetEnvelope, dims);
} else {
// build slice based on intersection
Envelope intersection = targetEnvelope.intersection(dataEnv);
rval = getSubSlice(geom, intersection, dims);
}
return rval;
}
/**
* @param geom
* grid geometry for projected dataset
* @param env
* geographic bounds for slice
* @param dims
* dimensions of dataset
* @return grid slice that corresponds to env
* @throws MismatchedDimensionException
* @throws TransformException
*/
protected static RequestWrapper getSubSlice(GridGeometry2D geom,
Envelope env,
int[] dims) throws MismatchedDimensionException, TransformException {
RequestWrapper rval = new RequestWrapper();
MathTransform2D crsToGrid2D = geom
.getCRSToGrid2D(PixelOrientation.UPPER_LEFT);
// find a slice that has data for entire envelope (can have extra)
int[][] minmax = transformEnv(crsToGrid2D, env, dims);
MathTransform2D gridToCrs = crsToGrid2D.inverse();
// find an envelope that matches the slice (could be a bit larger than
// previous envelope)
rval.env = transformGrid(gridToCrs, minmax,
geom.getCoordinateReferenceSystem());
rval.req = Request.buildSlab(minmax[0], minmax[1]);
return rval;
}
/**
* @param gridToCrs
* @param minmax
* 2d array holding slice
* @param crs
* @return
* @throws MismatchedDimensionException
* @throws TransformException
*/
protected static ReferencedEnvelope transformGrid(
MathTransform2D gridToCrs,
int[][] minmax, CoordinateReferenceSystem crs)
throws MismatchedDimensionException, TransformException {
int[] min = minmax[0];
int[] max = minmax[1];
DirectPosition lower = new DirectPosition2D(min[0], min[1]);
DirectPosition upper = new DirectPosition2D(max[0], max[1]);
DirectPosition lowerCrs = gridToCrs.transform(lower, null);
DirectPosition upperCrs = gridToCrs.transform(upper, null);
double x0 = lowerCrs.getOrdinate(0);
double x1 = upperCrs.getOrdinate(0);
// handle y axis flip
double y0 = upperCrs.getOrdinate(1);
double y1 = lowerCrs.getOrdinate(1);
return new ReferencedEnvelope(x0, x1, y0, y1, crs);
}
/**
* transforms crs coordinates to grid indexes using given math transform
*
* @param crsToGrid
* @param env
* @param dims
* max bounds to be limited to
* @return an array with [[minx, miny], [maxx, maxy]]
* @throws MismatchedDimensionException
* @throws TransformException
*/
protected static int[][] transformEnv(MathTransform2D crsToGrid,
Envelope env,
int[] dims) throws MismatchedDimensionException, TransformException {
DirectPosition lower = new DirectPosition2D(env.getMinX(),
env.getMinY());
DirectPosition upper = new DirectPosition2D(env.getMaxX(),
env.getMaxY());
DirectPosition lowerGrid = crsToGrid.transform(lower, null);
DirectPosition upperGrid = crsToGrid.transform(upper, null);
int x0 = (int) Math.floor(lowerGrid.getOrdinate(0));
// we want ceiling since slices are inclusive
int x1 = (int) Math.ceil(upperGrid.getOrdinate(0));
// handle y axis flip
int y0 = (int) Math.floor(upperGrid.getOrdinate(1));
// we want ceiling since slices are inclusive
int y1 = (int) Math.ceil(lowerGrid.getOrdinate(1));
// truncate requests to dataset dimensions
if (x0 < 0) {
x0 = 0;
}
if (y0 < 0) {
y0 = 0;
}
if (x1 > dims[0]) {
x1 = dims[0];
}
if (y1 > dims[1]) {
y1 = dims[1];
}
return new int[][] { { x0, y0 }, { x1, y1 } };
}
/**
* construct the dataset name based on the name of the crs.
*
* @param crs
* @return
*/
protected String buildDatasetName(CoordinateReferenceSystem crs) {
Set<ReferenceIdentifier> ids = crs.getIdentifiers();
String code;
if (ids == null || ids.isEmpty()) {
code = crs.getName().toString();
} else {
Iterator<ReferenceIdentifier> i = ids.iterator();
code = i.next().toString();
while (i.hasNext()) {
code += "-" + i.next().toString();
}
}
return dataSetBase + code;
}
public IDataStore getDataStore() {
return dataStore;
}
public void setDataStore(IDataStore dataStore) {
this.dataStore = dataStore;
}
public String getDataSetBase() {
return dataSetBase;
}
public void setDataSetBase(String dataSetBase) {
this.dataSetBase = dataSetBase;
}
public String getDataSet() {
return dataSet;
}
public void setDataSet(String dataSet) {
this.dataSet = dataSet;
}
}

View file

@ -1,246 +0,0 @@
/*
* The following software products were developed by Raytheon:
*
* ADE (AWIPS Development Environment) software
* CAVE (Common AWIPS Visualization Environment) software
* EDEX (Environmental Data Exchange) software
* uFrame (Universal Framework) software
*
* Copyright (c) 2010 Raytheon Co.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/epl-v10.php
*
*
* Contractor Name: Raytheon Company
* Contractor Address:
* 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 13, 2011 bclement Initial creation
*
*/
package com.raytheon.uf.common.spatial.reprojection;
import java.awt.Point;
import java.awt.image.DataBufferFloat;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.util.Arrays;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.raytheon.uf.common.datastorage.Request;
import com.raytheon.uf.common.datastorage.records.FloatDataRecord;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
/**
*
* @author bclement
* @version 1.0
*/
public class FloatDataReprojector extends
AbstractDataReprojector<FloatDataRecord> {
protected float fill = -999999.0f;
protected float dataMaskValue = -0;
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#getGridCoverage
* (com.raytheon.uf.common.datastorage.records.IDataRecord,
* org.opengis.referencing.crs.CoordinateReferenceSystem,
* org.opengis.geometry.Envelope)
*/
@Override
protected GridCoverage2D getGridCoverage(IDataRecord record,
ReferencedEnvelope env) throws Exception {
FloatDataRecord dataRecord = (FloatDataRecord) record;
float[] data = dataRecord.getFloatData();
DataBufferFloat buff = new DataBufferFloat(data, data.length);
int x = (int) dataRecord.getSizes()[0];
int y = (int) dataRecord.getSizes()[1];
CoordinateReferenceSystem crs = env.getCoordinateReferenceSystem();
return constructGridCoverage(crs.getName() + " Grid", buff, x, y, env);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#getMaskCoverage
* (com.raytheon.uf.common.datastorage.records.IDataRecord,
* org.opengis.referencing.crs.CoordinateReferenceSystem,
* org.opengis.geometry.Envelope)
*/
@Override
protected GridCoverage2D getMaskCoverage(IDataRecord record,
ReferencedEnvelope env) throws Exception {
int x = (int) record.getSizes()[0];
int y = (int) record.getSizes()[1];
float[] mask = new float[x * y];
Arrays.fill(mask, dataMaskValue);
DataBufferFloat buff = new DataBufferFloat(mask, mask.length);
CoordinateReferenceSystem crs = env.getCoordinateReferenceSystem();
return constructGridCoverage(crs.getName() + " Grid", buff, x, y, env);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#extractData(org
* .geotools.coverage.grid.GridCoverage2D)
*/
@Override
protected FloatDataRecord extractData(GridCoverage2D coverage) {
RenderedImage image = coverage.getRenderedImage();
Raster raster;
if (image.getNumXTiles() == 1 && image.getNumYTiles() == 1) {
// we can directly access data
raster = image.getTile(0, 0);
} else {
// need to copy data out
raster = image.getData();
}
DataBufferFloat dataBuffer = (DataBufferFloat) raster.getDataBuffer();
float[] data = dataBuffer.getData();
int height = raster.getHeight();
int width = raster.getWidth();
return new FloatDataRecord("", "", data, 2,
new long[] { width, height });
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#extractData(org
* .geotools.coverage.grid.GridCoverage2D,
* org.geotools.coverage.grid.GridCoverage2D)
*/
@Override
protected FloatDataRecord extractData(GridCoverage2D coverage,
GridCoverage2D maskCoverage) {
RenderedImage image = coverage.getRenderedImage();
Raster raster;
if (image.getNumXTiles() == 1 && image.getNumYTiles() == 1) {
// we can directly access data
raster = image.getTile(0, 0);
} else {
// need to copy data out
raster = image.getData();
}
DataBufferFloat dataBuffer = (DataBufferFloat) raster.getDataBuffer();
float[] data = dataBuffer.getData();
// Extract mask
image = maskCoverage.getRenderedImage();
if (image.getNumXTiles() == 1 && image.getNumYTiles() == 1) {
// we can directly access data
raster = image.getTile(0, 0);
} else {
// need to copy data out
raster = image.getData();
}
dataBuffer = (DataBufferFloat) raster.getDataBuffer();
float[] mask = dataBuffer.getData();
if (mask.length == data.length) {
for (int i = 0; i < data.length; ++i) {
if (mask[i] != dataMaskValue) {
data[i] = fill;
}
}
}
int height = raster.getHeight();
int width = raster.getWidth();
return new FloatDataRecord("", "", data, 2,
new long[] { width, height });
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#getDataSlice(com
* .raytheon.uf.common.datastorage.records.IDataRecord,
* com.raytheon.uf.common.datastorage.Request)
*/
@Override
protected FloatDataRecord getDataSlice(IDataRecord record, Request req) {
FloatDataRecord dataRecord = (FloatDataRecord) record;
int[] max = req.getMaxIndexForSlab();
int[] min = req.getMinIndexForSlab();
int toWidth = max[0] - min[0];
int toHeight = max[1] - min[1];
float[] from = dataRecord.getFloatData();
int fromWidth = (int) dataRecord.getSizes()[0];
float[] to = new float[toWidth * toHeight];
for (int fromY = min[1], toY = 0; fromY < max[1]; ++fromY, ++toY) {
int toRow = toY * toWidth;
int fromRow = fromY * fromWidth;
for (int fromX = min[0], toX = 0; fromX < max[0]; ++fromX, ++toX) {
to[toRow + toX] = from[fromRow + fromX];
}
}
long[] sizes = { toWidth, toHeight };
return new FloatDataRecord("", "", to, 2, sizes);
}
/**
* @return the fill
*/
public float getFill() {
return fill;
}
/**
* @param fill
* the fill to set
*/
public void setFill(float fill) {
this.fill = fill;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.AbstractDataReprojector#compatible
* (com.raytheon.uf.common.datastorage.records.IDataRecord)
*/
@Override
protected boolean compatible(IDataRecord dataRecord) {
return dataRecord instanceof FloatDataRecord;
}
@Override
protected IDataRecord getDataPoints(IDataRecord record, Request req) {
FloatDataRecord dataRecord = (FloatDataRecord) record;
float[] from = dataRecord.getFloatData();
int fromWidth = (int) dataRecord.getSizes()[0];
Point[] points = req.getPoints();
float[] to = new float[points.length];
for (int i = 0; i < to.length; ++i) {
Point p = points[i];
to[i] = from[p.y * fromWidth + p.x];
}
return new FloatDataRecord("", "", to, 1, new long[] { to.length });
}
}

View file

@ -1,247 +0,0 @@
/*
* The following software products were developed by Raytheon:
*
* ADE (AWIPS Development Environment) software
* CAVE (Common AWIPS Visualization Environment) software
* EDEX (Environmental Data Exchange) software
* uFrame (Universal Framework) software
*
* Copyright (c) 2010 Raytheon Co.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/epl-v10.php
*
*
* Contractor Name: Raytheon Company
* Contractor Address:
* 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 13, 2011 bclement Initial creation
*
*/
package com.raytheon.uf.common.spatial.reprojection;
import java.awt.Point;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.util.Arrays;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.raytheon.uf.common.datastorage.Request;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.datastorage.records.IntegerDataRecord;
/**
*
* @author bclement
* @version 1.0
*/
public class IntDataReprojector extends
AbstractDataReprojector<IntegerDataRecord> {
protected int fill = 0;
protected int dataMaskValue = -1;
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#getGridCoverage
* (com.raytheon.uf.common.datastorage.records.IDataRecord,
* org.opengis.referencing.crs.CoordinateReferenceSystem,
* org.opengis.geometry.Envelope)
*/
@Override
protected GridCoverage2D getGridCoverage(IDataRecord record,
ReferencedEnvelope env) throws Exception {
IntegerDataRecord dataRecord = (IntegerDataRecord) record;
int[] data = dataRecord.getIntData();
DataBuffer buff = new DataBufferInt(data, data.length);
int x = (int) dataRecord.getSizes()[0];
int y = (int) dataRecord.getSizes()[1];
CoordinateReferenceSystem crs = env.getCoordinateReferenceSystem();
return constructGridCoverage(crs.getName() + " Grid", buff, x, y, env);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#getMaskCoverage
* (com.raytheon.uf.common.datastorage.records.IDataRecord,
* org.opengis.referencing.crs.CoordinateReferenceSystem,
* org.opengis.geometry.Envelope)
*/
@Override
protected GridCoverage2D getMaskCoverage(IDataRecord record,
ReferencedEnvelope env) throws Exception {
int x = (int) record.getSizes()[0];
int y = (int) record.getSizes()[1];
int[] mask = new int[x * y];
Arrays.fill(mask, dataMaskValue);
DataBufferInt buff = new DataBufferInt(mask, mask.length);
CoordinateReferenceSystem crs = env.getCoordinateReferenceSystem();
return constructGridCoverage(crs.getName() + " Grid", buff, x, y, env);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#extractData(org
* .geotools.coverage.grid.GridCoverage2D)
*/
@Override
protected IntegerDataRecord extractData(GridCoverage2D coverage) {
RenderedImage image = coverage.getRenderedImage();
Raster raster;
if (image.getNumXTiles() == 1 && image.getNumYTiles() == 1) {
// we can directly access data
raster = image.getTile(0, 0);
} else {
// need to copy data out
raster = image.getData();
}
DataBufferInt dataBuffer = (DataBufferInt) raster.getDataBuffer();
int[] data = dataBuffer.getData();
int height = raster.getHeight();
int width = raster.getWidth();
return new IntegerDataRecord("", "", data, 2, new long[] { width,
height });
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#extractData(org
* .geotools.coverage.grid.GridCoverage2D,
* org.geotools.coverage.grid.GridCoverage2D)
*/
@Override
protected IntegerDataRecord extractData(GridCoverage2D coverage,
GridCoverage2D maskCoverage) {
RenderedImage image = coverage.getRenderedImage();
Raster raster;
if (image.getNumXTiles() == 1 && image.getNumYTiles() == 1) {
// we can directly access data
raster = image.getTile(0, 0);
} else {
// need to copy data out
raster = image.getData();
}
DataBufferInt dataBuffer = (DataBufferInt) raster.getDataBuffer();
int[] data = dataBuffer.getData();
// Extract mask
image = maskCoverage.getRenderedImage();
if (image.getNumXTiles() == 1 && image.getNumYTiles() == 1) {
// we can directly access data
raster = image.getTile(0, 0);
} else {
// need to copy data out
raster = image.getData();
}
dataBuffer = (DataBufferInt) raster.getDataBuffer();
int[] mask = dataBuffer.getData();
if (mask.length == data.length) {
for (int i = 0; i < data.length; ++i) {
if (mask[i] != dataMaskValue) {
data[i] = fill;
}
}
}
int height = raster.getHeight();
int width = raster.getWidth();
return new IntegerDataRecord("", "", data, 2, new long[] { width,
height });
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#getDataSlice(com
* .raytheon.uf.common.datastorage.records.IDataRecord,
* com.raytheon.uf.common.datastorage.Request)
*/
@Override
protected IntegerDataRecord getDataSlice(IDataRecord record, Request req) {
IntegerDataRecord dataRecord = (IntegerDataRecord) record;
int[] max = req.getMaxIndexForSlab();
int[] min = req.getMinIndexForSlab();
int toWidth = max[0] - min[0];
int toHeight = max[1] - min[1];
int[] from = dataRecord.getIntData();
int fromWidth = (int) dataRecord.getSizes()[0];
int[] to = new int[toWidth * toHeight];
for (int fromY = min[1], toY = 0; fromY < max[1]; ++fromY, ++toY) {
int toRow = toY * toWidth;
int fromRow = fromY * fromWidth;
for (int fromX = min[0], toX = 0; fromX < max[0]; ++fromX, ++toX) {
to[toRow + toX] = from[fromRow + fromX];
}
}
long[] sizes = { toWidth, toHeight };
return new IntegerDataRecord("", "", to, 2, sizes);
}
/**
* @return the fill
*/
public int getFill() {
return fill;
}
/**
* @param fill
* the fill to set
*/
public void setFill(int fill) {
this.fill = fill;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.AbstractDataReprojector#compatible
* (com.raytheon.uf.common.datastorage.records.IDataRecord)
*/
@Override
protected boolean compatible(IDataRecord dataRecord) {
return dataRecord instanceof IntegerDataRecord;
}
@Override
protected IDataRecord getDataPoints(IDataRecord record, Request req) {
IntegerDataRecord dataRecord = (IntegerDataRecord) record;
int[] from = dataRecord.getIntData();
int fromWidth = (int) dataRecord.getSizes()[0];
Point[] points = req.getPoints();
int[] to = new int[points.length];
for (int i = 0; i < to.length; ++i) {
Point p = points[i];
to[i] = from[p.y * fromWidth + p.x];
}
return new IntegerDataRecord("", "", to, 1, new long[] { to.length });
}
}

View file

@ -1,104 +0,0 @@
/*
* The following software products were developed by Raytheon:
*
* ADE (AWIPS Development Environment) software
* CAVE (Common AWIPS Visualization Environment) software
* EDEX (Environmental Data Exchange) software
* uFrame (Universal Framework) software
*
* Copyright (c) 2010 Raytheon Co.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/epl-v10.php
*
*
* Contractor Name: Raytheon Company
* Contractor Address:
* 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
*/
package com.raytheon.uf.common.spatial.reprojection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Class for managing a pool of concurrency locks organized by string keys.
*
* @author bclement
* @version 1.0
*/
public class KeyLocker {
public class KeyLock {
private final String key;
private final Lock lock;
private boolean released = false;
public KeyLock(String key, Lock lock) {
this.key = key;
this.lock = lock;
}
@Override
protected void finalize() throws Throwable {
release();
}
public void release() {
if (!this.released) {
releaseLock(this.key);
this.released = true;
}
}
public void lock() {
this.lock.lock();
}
public void unlock() {
this.lock.unlock();
}
}
private class Entry {
int count = 0;
final Lock lock = new ReentrantLock();
}
private final Map<String, Entry> locks = new HashMap<String, Entry>();
public KeyLock getLock(String key) {
synchronized (locks) {
Entry e = locks.get(key);
if (e == null) {
e = new Entry();
locks.put(key, e);
}
e.count++;
return new KeyLock(key, e.lock);
}
}
void releaseLock(String key) {
synchronized (locks) {
Entry e = locks.get(key);
if (e != null) {
e.count--;
if (e.count <= 0) {
locks.remove(key);
}
}
}
}
}

View file

@ -1,64 +0,0 @@
/*
* The following software products were developed by Raytheon:
*
* ADE (AWIPS Development Environment) software
* CAVE (Common AWIPS Visualization Environment) software
* EDEX (Environmental Data Exchange) software
* uFrame (Universal Framework) software
*
* Copyright (c) 2010 Raytheon Co.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/epl-v10.php
*
*
* Contractor Name: Raytheon Company
* Contractor Address:
* 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 18, 2011 bclement Initial creation
*
*/
package com.raytheon.uf.common.spatial.reprojection;
import org.geotools.geometry.jts.ReferencedEnvelope;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
public class ReferencedDataRecord{
protected IDataRecord record;
protected ReferencedEnvelope envelope;
public ReferencedDataRecord(IDataRecord record, ReferencedEnvelope envlope) {
this.record = record;
this.envelope = envlope;
}
public IDataRecord getRecord() {
return record;
}
public void setRecord(IDataRecord record) {
this.record = record;
}
public ReferencedEnvelope getEnvelope() {
return envelope;
}
public void setEnvelope(ReferencedEnvelope envelope) {
this.envelope = envelope;
}
}

View file

@ -1,248 +0,0 @@
/*
* The following software products were developed by Raytheon:
*
* ADE (AWIPS Development Environment) software
* CAVE (Common AWIPS Visualization Environment) software
* EDEX (Environmental Data Exchange) software
* uFrame (Universal Framework) software
*
* Copyright (c) 2010 Raytheon Co.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/epl-v10.php
*
*
* Contractor Name: Raytheon Company
* Contractor Address:
* 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 13, 2011 bclement Initial creation
*
*/
package com.raytheon.uf.common.spatial.reprojection;
import java.awt.Point;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferShort;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.util.Arrays;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.raytheon.uf.common.datastorage.Request;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.datastorage.records.ShortDataRecord;
/**
* TODO Add Description
*
* @author bclement
* @version 1.0
*/
public class ShortDataReprojector extends
AbstractDataReprojector<ShortDataRecord> {
protected short fill = 0;
protected short dataMaskValue = -1;
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#getGridCoverage
* (com.raytheon.uf.common.datastorage.records.IDataRecord,
* org.opengis.referencing.crs.CoordinateReferenceSystem,
* org.opengis.geometry.Envelope)
*/
@Override
protected GridCoverage2D getGridCoverage(IDataRecord record,
ReferencedEnvelope env) throws Exception {
ShortDataRecord dataRecord = (ShortDataRecord) record;
short[] data = dataRecord.getShortData();
DataBuffer buff = new DataBufferShort(data, data.length);
int x = (int) dataRecord.getSizes()[0];
int y = (int) dataRecord.getSizes()[1];
CoordinateReferenceSystem crs = env.getCoordinateReferenceSystem();
return constructGridCoverage(crs.getName() + " Grid", buff, x, y, env);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#getMaskCoverage
* (com.raytheon.uf.common.datastorage.records.IDataRecord,
* org.opengis.referencing.crs.CoordinateReferenceSystem,
* org.opengis.geometry.Envelope)
*/
@Override
protected GridCoverage2D getMaskCoverage(IDataRecord record,
ReferencedEnvelope env) throws Exception {
int x = (int) record.getSizes()[0];
int y = (int) record.getSizes()[1];
short[] mask = new short[x * y];
Arrays.fill(mask, dataMaskValue);
DataBufferShort buff = new DataBufferShort(mask, mask.length);
CoordinateReferenceSystem crs = env.getCoordinateReferenceSystem();
return constructGridCoverage(crs.getName() + " Grid", buff, x, y, env);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#extractData(org
* .geotools.coverage.grid.GridCoverage2D)
*/
@Override
protected ShortDataRecord extractData(GridCoverage2D coverage) {
RenderedImage image = coverage.getRenderedImage();
Raster raster;
if (image.getNumXTiles() == 1 && image.getNumYTiles() == 1) {
// we can directly access data
raster = image.getTile(0, 0);
} else {
// need to copy data out
raster = image.getData();
}
DataBufferShort dataBuffer = (DataBufferShort) raster.getDataBuffer();
short[] data = dataBuffer.getData();
int height = raster.getHeight();
int width = raster.getWidth();
return new ShortDataRecord("", "", data, 2,
new long[] { width, height });
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#extractData(org
* .geotools.coverage.grid.GridCoverage2D,
* org.geotools.coverage.grid.GridCoverage2D)
*/
@Override
protected ShortDataRecord extractData(GridCoverage2D coverage,
GridCoverage2D maskCoverage) {
RenderedImage image = coverage.getRenderedImage();
Raster raster;
if (image.getNumXTiles() == 1 && image.getNumYTiles() == 1) {
// we can directly access data
raster = image.getTile(0, 0);
} else {
// need to copy data out
raster = image.getData();
}
DataBufferShort dataBuffer = (DataBufferShort) raster.getDataBuffer();
short[] data = dataBuffer.getData();
// Extract mask
image = maskCoverage.getRenderedImage();
if (image.getNumXTiles() == 1 && image.getNumYTiles() == 1) {
// we can directly access data
raster = image.getTile(0, 0);
} else {
// need to copy data out
raster = image.getData();
}
dataBuffer = (DataBufferShort) raster.getDataBuffer();
short[] mask = dataBuffer.getData();
if (mask.length == data.length) {
for (int i = 0; i < data.length; ++i) {
if (mask[i] != dataMaskValue) {
data[i] = fill;
}
}
}
int height = raster.getHeight();
int width = raster.getWidth();
return new ShortDataRecord("", "", data, 2,
new long[] { width, height });
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.DataReprojector#getDataSlice(com
* .raytheon.uf.common.datastorage.records.IDataRecord,
* com.raytheon.uf.common.datastorage.Request)
*/
@Override
protected ShortDataRecord getDataSlice(IDataRecord record, Request req) {
ShortDataRecord dataRecord = (ShortDataRecord) record;
int[] max = req.getMaxIndexForSlab();
int[] min = req.getMinIndexForSlab();
int toWidth = max[0] - min[0];
int toHeight = max[1] - min[1];
short[] from = dataRecord.getShortData();
int fromWidth = (int) dataRecord.getSizes()[0];
short[] to = new short[toWidth * toHeight];
for (int fromY = min[1], toY = 0; fromY < max[1]; ++fromY, ++toY) {
int toRow = toY * toWidth;
int fromRow = fromY * fromWidth;
for (int fromX = min[0], toX = 0; fromX < max[0]; ++fromX, ++toX) {
to[toRow + toX] = from[fromRow + fromX];
}
}
long[] sizes = { toWidth, toHeight };
return new ShortDataRecord("", "", to, 2, sizes);
}
/**
* @return the fill
*/
public short getFill() {
return fill;
}
/**
* @param fill
* the fill to set
*/
public void setFill(short fill) {
this.fill = fill;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.spatial.reprojection.AbstractDataReprojector#compatible
* (com.raytheon.uf.common.datastorage.records.IDataRecord)
*/
@Override
protected boolean compatible(IDataRecord dataRecord) {
return dataRecord instanceof ShortDataRecord;
}
@Override
protected IDataRecord getDataPoints(IDataRecord record, Request req) {
ShortDataRecord dataRecord = (ShortDataRecord) record;
short[] from = dataRecord.getShortData();
int fromWidth = (int) dataRecord.getSizes()[0];
Point[] points = req.getPoints();
short[] to = new short[points.length];
for (int i = 0; i < to.length; ++i) {
Point p = points[i];
to[i] = from[p.y * fromWidth + p.x];
}
return new ShortDataRecord("", "", to, 1, new long[] { to.length });
}
}

View file

@ -12,6 +12,7 @@ Require-Bundle: org.apache.commons.beanutils;bundle-version="1.8.3",
Export-Package: com.raytheon.uf.common.util,
com.raytheon.uf.common.util.algorithm,
com.raytheon.uf.common.util.cache,
com.raytheon.uf.common.util.concurrent,
com.raytheon.uf.common.util.file,
com.raytheon.uf.common.util.header,
com.raytheon.uf.common.util.mapping,

View file

@ -2,4 +2,3 @@ source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.
src.excludes = test/src/

View file

@ -0,0 +1,88 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.util.concurrent;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Lock assigned to a key
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 8, 2013 bclement moved from KeyLocker internal class
*
* </pre>
*
* @author bclement
* @version 1.0
*/
public class KeyLock<K> {
private final K key;
private final ReentrantReadWriteLock lock;
public KeyLock(K key, ReentrantReadWriteLock lock) {
this.key = key;
this.lock = lock;
}
/**
* Acquire write lock
*/
public void lock() {
this.lock.writeLock().lock();
}
/**
* Let go of write lock
*/
public void unlock() {
this.lock.writeLock().unlock();
}
/**
* Acquire read lock
*/
public void readLock() {
this.lock.readLock().lock();
}
/**
* Let go of read lock
*/
public void readUnlock() {
this.lock.readLock().unlock();
}
/**
*
* @return the key
*/
public K getKey() {
return key;
}
}

View file

@ -0,0 +1,130 @@
/*
* The following software products were developed by Raytheon:
*
* ADE (AWIPS Development Environment) software
* CAVE (Common AWIPS Visualization Environment) software
* EDEX (Environmental Data Exchange) software
* uFrame (Universal Framework) software
*
* Copyright (c) 2010 Raytheon Co.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/epl-v10.php
*
*
* Contractor Name: Raytheon Company
* Contractor Address:
* 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
*/
package com.raytheon.uf.common.util.concurrent;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Manages a pool of locks assigned to keys. Allows for synchronizing expensive
* tasks on a per-key basis.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 18, 2011 bclement Initial creation
* Nov 8, 2013 1314 bclement moved to common.util
*
* </pre>
*
* @author bclement
* @version 1.0
*/
public class KeyLocker<K> {
private final boolean fair;
public KeyLocker() {
this(false);
}
/**
* @param fair
* true if created locks should use a fair ordering policy
*/
public KeyLocker(boolean fair) {
this.fair = fair;
}
/**
* Weak reference to lock that keeps track of the key used to clean the lock
* map
*
* @author bclement
* @version 1.0
*/
private class WeakKeyLock extends WeakReference<ReentrantReadWriteLock> {
public final K key;
public WeakKeyLock(K key, ReentrantReadWriteLock referent,
ReferenceQueue<? super ReentrantReadWriteLock> q) {
super(referent, q);
this.key = key;
}
}
private final Map<K, WeakKeyLock> locks = new HashMap<K, WeakKeyLock>();
private final ReferenceQueue<ReentrantReadWriteLock> refQueue = new ReferenceQueue<ReentrantReadWriteLock>();
/**
* Get lock associated with key.
*
* @param key
* @return
*/
public KeyLock<K> getLock(K key) {
synchronized (locks) {
cleanUp();
WeakReference<ReentrantReadWriteLock> weakLock = locks.get(key);
ReentrantReadWriteLock lock = null;
if (weakLock != null) {
lock = weakLock.get();
}
if (lock == null) {
lock = new ReentrantReadWriteLock(fair);
locks.put(key, new WeakKeyLock(key, lock, refQueue));
}
return new KeyLock<K>(key, lock);
}
}
/**
* Poll weak reference and remove from locks map. Must be externally
* synchronized.
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private void cleanUp() {
Reference<? extends ReentrantReadWriteLock> unused = refQueue.poll();
while (unused != null) {
if (unused instanceof KeyLocker.WeakKeyLock) {
WeakKeyLock wkl = (KeyLocker.WeakKeyLock) unused;
locks.remove(wkl.key);
}
unused = refQueue.poll();
}
}
}

View file

@ -53,13 +53,6 @@
version="0.0.0"
unpack="false"/>
<plugin
id="com.raytheon.uf.common.spatial"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.raytheon.uf.common.datadelivery.retrieval"
download-size="0"
@ -107,7 +100,7 @@
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.raytheon.uf.edex.datadelivery.event"
download-size="0"

View file

@ -17,7 +17,6 @@ Require-Bundle: net.opengis;bundle-version="1.0.2",
com.raytheon.uf.common.json;bundle-version="1.0.0",
com.sun.xml.bind;bundle-version="1.0.0",
com.raytheon.uf.common.status;bundle-version="1.12.1174",
com.raytheon.uf.common.spatial;bundle-version="1.0.0",
com.raytheon.uf.common.pointdata;bundle-version="1.12.1174",
ogc.tools.gml;bundle-version="1.0.2",
org.apache.commons.cxf,

View file

@ -24,8 +24,8 @@ import java.util.Map;
import org.apache.commons.collections.map.LRUMap;
import com.raytheon.uf.common.spatial.reprojection.KeyLocker;
import com.raytheon.uf.common.spatial.reprojection.KeyLocker.KeyLock;
import com.raytheon.uf.common.util.concurrent.KeyLock;
import com.raytheon.uf.common.util.concurrent.KeyLocker;
import com.raytheon.uf.edex.ogc.common.OgcException.Code;
/**
@ -39,6 +39,7 @@ import com.raytheon.uf.edex.ogc.common.OgcException.Code;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 15, 2013 bclement Initial creation
* Nov 8, 2013 1314 bclement updated lock to use read/write
*
* </pre>
*
@ -62,7 +63,7 @@ public abstract class AbstractFSQueryStore<T> extends AbstractFsStore {
private final Map<String, String> strCache = Collections
.synchronizedMap(new LRUMap(2));
private final KeyLocker locker = new KeyLocker();
private final KeyLocker<String> locker = new KeyLocker<String>();
/**
* @param id
@ -70,13 +71,12 @@ public abstract class AbstractFSQueryStore<T> extends AbstractFsStore {
* @throws Exception
*/
public void store(String id, T query) throws OgcException {
KeyLock lock = locker.getLock(id);
KeyLock<String> lock = locker.getLock(id);
lock.lock();
try {
storeObject(id, query);
} finally {
lock.unlock();
lock.release();
}
}
@ -130,13 +130,12 @@ public abstract class AbstractFSQueryStore<T> extends AbstractFsStore {
*/
public T retrieve(String id) throws OgcException {
T rval;
KeyLock lock = locker.getLock(id);
lock.lock();
KeyLock<String> lock = locker.getLock(id);
lock.readLock();
try {
rval = retrieveObject(id);
} finally {
lock.unlock();
lock.release();
lock.readUnlock();
}
return rval;
}
@ -199,13 +198,12 @@ public abstract class AbstractFSQueryStore<T> extends AbstractFsStore {
* @throws Exception
*/
protected String retrieveString(String id) throws OgcException {
KeyLock lock = locker.getLock(id);
lock.lock();
KeyLock<String> lock = locker.getLock(id);
lock.readLock();
try {
return retrieveStringInternal(id);
} finally {
lock.unlock();
lock.release();
lock.readUnlock();
}
}
@ -216,7 +214,7 @@ public abstract class AbstractFSQueryStore<T> extends AbstractFsStore {
* com.raytheon.uf.edex.wfs.querystore.QueryStore#remove(java.lang.String)
*/
public void remove(String id) {
KeyLock lock = locker.getLock(id);
KeyLock<String> lock = locker.getLock(id);
lock.lock();
try {
objCache.remove(id);
@ -227,7 +225,6 @@ public abstract class AbstractFSQueryStore<T> extends AbstractFsStore {
}
} finally {
lock.unlock();
lock.release();
}
}

View file

@ -1,195 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.edex.ogc.common.spatial;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.persist.IPersistable;
import com.raytheon.uf.common.datastorage.IDataStore;
import com.raytheon.uf.common.datastorage.records.ByteDataRecord;
import com.raytheon.uf.common.datastorage.records.FloatDataRecord;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.datastorage.records.IntegerDataRecord;
import com.raytheon.uf.common.geospatial.ISpatialEnabled;
import com.raytheon.uf.common.geospatial.ISpatialObject;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.spatial.reprojection.DataReprojector;
import com.raytheon.uf.common.spatial.reprojection.ReferencedDataRecord;
import com.raytheon.uf.edex.database.plugin.PluginDao;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Polygon;
/**
* Utility methods for reprojecting data records. Removing code only used by ogc
* services from {@link PluginDao} to here
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 26, 2013 1638 mschenke Code moved from PluginDao to clean up dependencies
*
* </pre>
*
* @author unknown
* @version 1.0
*/
public class RecordUtil {
/**
* @param record
* @param crs
* target crs for projected data
* @param envelope
* bounding box in target crs
* @return null if envelope is disjoint with data bounds
* @throws Exception
*/
public static ReferencedDataRecord getProjected(PluginDao dao,
PluginDataObject record, CoordinateReferenceSystem crs,
Envelope envelope) throws Exception {
ReferencedEnvelope targetEnv = new ReferencedEnvelope(
envelope.getMinX(), envelope.getMaxX(), envelope.getMinY(),
envelope.getMaxY(), crs);
return getProjected(dao, record, targetEnv);
}
public static double getHDF5Value(PluginDao dao, PluginDataObject pdo,
CoordinateReferenceSystem crs, Coordinate coord,
double defaultReturn) throws Exception {
// TODO a cache would probably be good here
double rval = defaultReturn;
if (pdo instanceof ISpatialEnabled) {
IDataStore store = dao.getDataStore((IPersistable) pdo);
ISpatialObject spat = getSpatialObject(pdo);
DataReprojector reprojector = getDataReprojector(store);
ReferencedEnvelope nativeEnv = getNativeEnvelope(spat);
IDataRecord data = reprojector.getProjectedPoints(pdo.getDataURI(),
spat, nativeEnv, crs, new Coordinate[] { coord });
Double res = extractSingle(data);
if (res != null) {
rval = res;
}
}
return rval;
}
/**
* @param record
* @param crs
* target crs for projected data
* @param envelope
* bounding box in target crs
* @return null if envelope is disjoint with data bounds
* @throws Exception
*/
public static GridCoverage2D getProjectedCoverage(PluginDao dao,
PluginDataObject record, CoordinateReferenceSystem crs,
Envelope envelope) throws Exception {
ReferencedEnvelope targetEnv = new ReferencedEnvelope(
envelope.getMinX(), envelope.getMaxX(), envelope.getMinY(),
envelope.getMaxY(), crs);
return getProjectedCoverage(dao, record, targetEnv);
}
/**
* @param record
* @param targetEnvelope
* bounding box in target crs
* @return null if envelope is disjoint with data bounds
* @throws Exception
*/
public static ReferencedDataRecord getProjected(PluginDao dao,
PluginDataObject record, ReferencedEnvelope targetEnvelope)
throws Exception {
IDataStore store = dao.getDataStore((IPersistable) record);
ISpatialObject spatial = getSpatialObject(record);
DataReprojector reprojector = getDataReprojector(store);
ReferencedEnvelope nativeEnvelope = getNativeEnvelope(spatial);
return reprojector.getReprojected(record.getDataURI(), spatial,
nativeEnvelope, targetEnvelope);
}
/**
* @param record
* @param targetEnvelope
* bounding box in target crs
* @return null if envelope is disjoint with data bounds
* @throws Exception
*/
public static GridCoverage2D getProjectedCoverage(PluginDao dao,
PluginDataObject record, ReferencedEnvelope envelope)
throws Exception {
IDataStore store = dao.getDataStore((IPersistable) record);
ISpatialObject spatial = getSpatialObject(record);
DataReprojector reprojector = getDataReprojector(store);
ReferencedEnvelope nativeEnvelope = getNativeEnvelope(spatial);
return reprojector.getReprojectedCoverage(record.getDataURI(), spatial,
nativeEnvelope, envelope);
}
public static DataReprojector getDataReprojector(IDataStore dataStore) {
return new DataReprojector(dataStore);
}
public static ReferencedEnvelope getNativeEnvelope(ISpatialObject spatial)
throws FactoryException {
CoordinateReferenceSystem crs = spatial.getCrs();
Geometry geom = spatial.getGeometry();
return MapUtil.getBoundingEnvelope(crs, (Polygon) geom);
}
public static Double extractSingle(IDataRecord record) {
Double rval = null;
if (record == null) {
return rval;
}
if (record instanceof ByteDataRecord) {
byte[] data = ((ByteDataRecord) record).getByteData();
rval = (double) data[0];
} else if (record instanceof FloatDataRecord) {
float[] data = ((FloatDataRecord) record).getFloatData();
rval = (double) data[0];
} else if (record instanceof IntegerDataRecord) {
int[] data = ((IntegerDataRecord) record).getIntData();
rval = (double) data[0];
}
return rval;
}
public static ISpatialObject getSpatialObject(PluginDataObject record)
throws Exception {
if (record instanceof ISpatialEnabled) {
return ((ISpatialEnabled) record).getSpatialObject();
} else {
throw new Exception(record.getClass() + " is not spatially enabled");
}
}
}

View file

@ -22,7 +22,6 @@ Require-Bundle: org.geotools;bundle-version="2.6.4",
com.raytheon.uf.common.datadelivery.registry;bundle-version="1.0.0",
javax.measure;bundle-version="1.0.0",
com.sun.xml.bind;bundle-version="1.0.0",
com.raytheon.uf.common.spatial;bundle-version="1.0.0",
org.w3.xmlschema;bundle-version="1.0.0",
com.raytheon.uf.common.pointdata;bundle-version="1.12.1174",
org.apache.commons.collections;bundle-version="3.2.0",