Issue #1314 removed common.spatial plugin
Moved KeyLocker to common.util Updated query store to use read write lock Former-commit-id:4a97229443
[formerlyf994d9924d
] [formerly8142ff770f
] [formerly04791b7939
[formerly8142ff770f
[formerly 4f3d7e982a34f17fdf8cd80f025da176f939a3b1]]] Former-commit-id:04791b7939
Former-commit-id: e1ff87a68f53adadd668ab79157a662d8a5660e4 [formerlyf96f92df0b
] Former-commit-id:90682b4beb
This commit is contained in:
parent
a57b316541
commit
715edf805e
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,
|
Export-Package: com.raytheon.uf.common.util,
|
||||||
com.raytheon.uf.common.util.algorithm,
|
com.raytheon.uf.common.util.algorithm,
|
||||||
com.raytheon.uf.common.util.cache,
|
com.raytheon.uf.common.util.cache,
|
||||||
|
com.raytheon.uf.common.util.concurrent,
|
||||||
com.raytheon.uf.common.util.file,
|
com.raytheon.uf.common.util.file,
|
||||||
com.raytheon.uf.common.util.header,
|
com.raytheon.uf.common.util.header,
|
||||||
com.raytheon.uf.common.util.mapping,
|
com.raytheon.uf.common.util.mapping,
|
||||||
|
|
|
@ -2,4 +2,3 @@ source.. = src/
|
||||||
output.. = bin/
|
output.. = bin/
|
||||||
bin.includes = META-INF/,\
|
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"
|
version="0.0.0"
|
||||||
unpack="false"/>
|
unpack="false"/>
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="com.raytheon.uf.common.spatial"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
<plugin
|
||||||
id="com.raytheon.uf.common.datadelivery.retrieval"
|
id="com.raytheon.uf.common.datadelivery.retrieval"
|
||||||
download-size="0"
|
download-size="0"
|
||||||
|
@ -107,7 +100,7 @@
|
||||||
install-size="0"
|
install-size="0"
|
||||||
version="0.0.0"
|
version="0.0.0"
|
||||||
unpack="false"/>
|
unpack="false"/>
|
||||||
|
|
||||||
<plugin
|
<plugin
|
||||||
id="com.raytheon.uf.edex.datadelivery.event"
|
id="com.raytheon.uf.edex.datadelivery.event"
|
||||||
download-size="0"
|
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.raytheon.uf.common.json;bundle-version="1.0.0",
|
||||||
com.sun.xml.bind;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.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",
|
com.raytheon.uf.common.pointdata;bundle-version="1.12.1174",
|
||||||
ogc.tools.gml;bundle-version="1.0.2",
|
ogc.tools.gml;bundle-version="1.0.2",
|
||||||
org.apache.commons.cxf,
|
org.apache.commons.cxf,
|
||||||
|
|
|
@ -24,8 +24,8 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.apache.commons.collections.map.LRUMap;
|
import org.apache.commons.collections.map.LRUMap;
|
||||||
|
|
||||||
import com.raytheon.uf.common.spatial.reprojection.KeyLocker;
|
import com.raytheon.uf.common.util.concurrent.KeyLock;
|
||||||
import com.raytheon.uf.common.spatial.reprojection.KeyLocker.KeyLock;
|
import com.raytheon.uf.common.util.concurrent.KeyLocker;
|
||||||
import com.raytheon.uf.edex.ogc.common.OgcException.Code;
|
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
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Feb 15, 2013 bclement Initial creation
|
* Feb 15, 2013 bclement Initial creation
|
||||||
|
* Nov 8, 2013 1314 bclement updated lock to use read/write
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -62,7 +63,7 @@ public abstract class AbstractFSQueryStore<T> extends AbstractFsStore {
|
||||||
private final Map<String, String> strCache = Collections
|
private final Map<String, String> strCache = Collections
|
||||||
.synchronizedMap(new LRUMap(2));
|
.synchronizedMap(new LRUMap(2));
|
||||||
|
|
||||||
private final KeyLocker locker = new KeyLocker();
|
private final KeyLocker<String> locker = new KeyLocker<String>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id
|
* @param id
|
||||||
|
@ -70,13 +71,12 @@ public abstract class AbstractFSQueryStore<T> extends AbstractFsStore {
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public void store(String id, T query) throws OgcException {
|
public void store(String id, T query) throws OgcException {
|
||||||
KeyLock lock = locker.getLock(id);
|
KeyLock<String> lock = locker.getLock(id);
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
storeObject(id, query);
|
storeObject(id, query);
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
lock.release();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,13 +130,12 @@ public abstract class AbstractFSQueryStore<T> extends AbstractFsStore {
|
||||||
*/
|
*/
|
||||||
public T retrieve(String id) throws OgcException {
|
public T retrieve(String id) throws OgcException {
|
||||||
T rval;
|
T rval;
|
||||||
KeyLock lock = locker.getLock(id);
|
KeyLock<String> lock = locker.getLock(id);
|
||||||
lock.lock();
|
lock.readLock();
|
||||||
try {
|
try {
|
||||||
rval = retrieveObject(id);
|
rval = retrieveObject(id);
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.readUnlock();
|
||||||
lock.release();
|
|
||||||
}
|
}
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
@ -199,13 +198,12 @@ public abstract class AbstractFSQueryStore<T> extends AbstractFsStore {
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected String retrieveString(String id) throws OgcException {
|
protected String retrieveString(String id) throws OgcException {
|
||||||
KeyLock lock = locker.getLock(id);
|
KeyLock<String> lock = locker.getLock(id);
|
||||||
lock.lock();
|
lock.readLock();
|
||||||
try {
|
try {
|
||||||
return retrieveStringInternal(id);
|
return retrieveStringInternal(id);
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.readUnlock();
|
||||||
lock.release();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +214,7 @@ public abstract class AbstractFSQueryStore<T> extends AbstractFsStore {
|
||||||
* com.raytheon.uf.edex.wfs.querystore.QueryStore#remove(java.lang.String)
|
* com.raytheon.uf.edex.wfs.querystore.QueryStore#remove(java.lang.String)
|
||||||
*/
|
*/
|
||||||
public void remove(String id) {
|
public void remove(String id) {
|
||||||
KeyLock lock = locker.getLock(id);
|
KeyLock<String> lock = locker.getLock(id);
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
objCache.remove(id);
|
objCache.remove(id);
|
||||||
|
@ -227,7 +225,6 @@ public abstract class AbstractFSQueryStore<T> extends AbstractFsStore {
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
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",
|
com.raytheon.uf.common.datadelivery.registry;bundle-version="1.0.0",
|
||||||
javax.measure;bundle-version="1.0.0",
|
javax.measure;bundle-version="1.0.0",
|
||||||
com.sun.xml.bind;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",
|
org.w3.xmlschema;bundle-version="1.0.0",
|
||||||
com.raytheon.uf.common.pointdata;bundle-version="1.12.1174",
|
com.raytheon.uf.common.pointdata;bundle-version="1.12.1174",
|
||||||
org.apache.commons.collections;bundle-version="3.2.0",
|
org.apache.commons.collections;bundle-version="3.2.0",
|
||||||
|
|
Loading…
Add table
Reference in a new issue