Merge "Issue #1314 removed common.spatial plugin" into development
Former-commit-id: 823cb0e07793ec5baa1863088634a312364b3d8b
This commit is contained in:
commit
0dbc31b756
23 changed files with 232 additions and 2213 deletions
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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 });
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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 });
|
||||
}
|
||||
|
||||
}
|
|
@ -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 });
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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 });
|
||||
}
|
||||
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -2,4 +2,3 @@ source.. = src/
|
|||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
||||
src.excludes = test/src/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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",
|
||||
|
|
Loading…
Add table
Reference in a new issue