Issue #1446 add getLatCoords and getLonCoords to python data access framework

Change-Id: I292a9b424cadf3033a861d8a0703b2f02946cd4e

Former-commit-id: af22cf8929 [formerly af22cf8929 [formerly 30ffd1412f3b193ce1fe2560f2ecf29027e7f619]]
Former-commit-id: b84af90fc2
Former-commit-id: 177d02d01b
This commit is contained in:
Matt Nash 2013-01-17 16:06:01 -06:00
parent 02f52c800e
commit 2e6ba707e9
5 changed files with 218 additions and 24 deletions

View file

@ -69,10 +69,14 @@ class JGridData(IGridData, JData.JData):
unitObj = UnitFormat.getUCUMInstance().parseObject(unit) unitObj = UnitFormat.getUCUMInstance().parseObject(unit)
converter = self.jobj.getUnit().getConverterTo(unitObj) converter = self.jobj.getUnit().getConverterTo(unitObj)
unitDest = UnitConvertingDataDestination(converter, dest) unitDest = UnitConvertingDataDestination(converter, dest)
filledDest = self.jobj.populateDataDestination(unitDest) filledDest = self.jobj.populateData(unitDest)
pnfa = PythonNumpyFloatArray(filledDest.getWrappedDestination().getFloatArray()) nx = self.jobj.getGridGeometry().getGridRange().getSpan(0)
ny = self.jobj.getGridGeometry().getGridRange().getSpan(1)
pnfa = PythonNumpyFloatArray(filledDest.getWrappedDestination().getArray(), nx, ny)
else: else:
filledDest = self.jobj.populateDataDestination(dest) filledDest = self.jobj.populateData(dest)
pnfa = PythonNumpyFloatArray(dest.getFloatArray()) nx = self.jobj.getGridGeometry().getGridRange().getSpan(0);
ny = self.jobj.getGridGeometry().getGridRange().getSpan(1);
pnfa = PythonNumpyFloatArray(dest.getArray(), nx, ny)
return pnfa.__numpy__[0] return pnfa.__numpy__[0]

View file

@ -1,4 +1,4 @@
## # #
# This software was developed and / or modified by Raytheon Company, # This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government. # pursuant to Contract DG133W-05-CQ-1067 with the US Government.
# #
@ -16,7 +16,7 @@
# #
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for # See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information. # further licensing information.
## # #
# #
@ -39,6 +39,8 @@ from ufpy.dataaccess import IGeometryRequest, IGridRequest
from com.raytheon.uf.common.dataaccess import DataAccessLayer as JavaDataAccessLayer from com.raytheon.uf.common.dataaccess import DataAccessLayer as JavaDataAccessLayer
from com.raytheon.uf.common.dataaccess.impl import DefaultGridRequest, DefaultGeometryRequest from com.raytheon.uf.common.dataaccess.impl import DefaultGridRequest, DefaultGeometryRequest
from com.raytheon.uf.common.time import DataTime as JavaDataTime from com.raytheon.uf.common.time import DataTime as JavaDataTime
from com.raytheon.uf.common.geospatial import LatLonReprojection
from com.raytheon.uf.common.python import PythonNumpyFloatArray
import jep import jep
import DataTime import DataTime
@ -73,15 +75,17 @@ def getData(request, times):
data.append(wrapper(jd)) data.append(wrapper(jd))
return data return data
def getLatCoords(gridRequest): def getLatLonCoords(gridRequest):
# TODO need to request the GridGeometry, then translate it into lat/lons '''
# Ben has ideas about how to do this fast @return: a tuple where the first element is a numpy array of lons, and the second element is a numpy array of lats
pass '''
gridGeometry = JavaDataAccessLayer.getGridGeometry(gridRequest.toJavaObj())
def getLonCoords(gridRequest): latlons = LatLonReprojection.getLatLons(gridGeometry)
# TODO need to request the GridGeometry, then translate it into lat/lons nx = gridGeometry.getGridRange().getSpan(0)
# Ben has ideas about how to do this fast ny = gridGeometry.getGridRange().getSpan(1)
pass latndarray = PythonNumpyFloatArray(latlons.getLats(), nx, ny).__numpy__[0]
lonndarray = PythonNumpyFloatArray(latlons.getLons(), nx, ny).__numpy__[0]
return (lonndarray, latndarray)
def getAvailableLocationNames(geometryRequest): def getAvailableLocationNames(geometryRequest):
return JavaDataAccessLayer.getAvailableLocationNames(geometryRequest.toJavaObj()) return JavaDataAccessLayer.getAvailableLocationNames(geometryRequest.toJavaObj())

View file

@ -0,0 +1,122 @@
/**
* 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.geospatial;
import org.geotools.coverage.grid.GeneralGridGeometry;
import org.geotools.coverage.grid.InvalidGridGeometryException;
import org.geotools.referencing.operation.DefaultMathTransformFactory;
import org.geotools.referencing.operation.projection.ProjectionException;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
/**
* Convert a {@link GeneralGridGeometry} to Lat/Lon projection, with methods for
* retrieving just the lats and just the lons
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 15, 2013 mnash Initial creation
*
* </pre>
*
* @author mnash
* @version 1.0
*/
public class LatLonReprojection {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(LatLonReprojection.class);
/**
* Take a {@link GeneralGridGeometry} and reproject it to lat/lon space
*
* @param source
* @return float[] of all lat/lon points
*/
private static float[] reproject(GeneralGridGeometry source) {
MathTransform gridToCRS = source.getGridToCRS(PixelInCell.CELL_CENTER);
DefaultMathTransformFactory mtf = new DefaultMathTransformFactory();
int sourceNx = source.getGridRange().getSpan(0);
int sourceNy = source.getGridRange().getSpan(1);
float[] transformTable = new float[sourceNx * sourceNy * 2];
try {
// create a concatenated transform with the one above and to
// lat/lon
MathTransform finalTransform = null;
finalTransform = mtf.createConcatenatedTransform(gridToCRS,
MapUtil.getTransformToLatLon(source
.getCoordinateReferenceSystem()));
int index = 0;
for (int j = 0; j < sourceNy; j++) {
for (int i = 0; i < sourceNx; i++) {
transformTable[index++] = i;
transformTable[index++] = j;
}
}
finalTransform.transform(transformTable, 0, transformTable, 0,
sourceNx * sourceNy);
} catch (ProjectionException e) {
// do nothing
} catch (TransformException e) {
statusHandler.handle(Priority.ERROR,
"Unable to transform to Lat/Lon projection", e);
} catch (InvalidGridGeometryException e) {
statusHandler.handle(Priority.ERROR, "Grid geometry is invalid", e);
} catch (FactoryException e) {
statusHandler.handle(Priority.ERROR, e.getLocalizedMessage(), e);
}
return transformTable;
}
/**
* Get the latitudes as an array after being reprojected
*
* @param source
* @return
*/
public static LatLonWrapper getLatLons(GeneralGridGeometry source) {
float[] latlons = reproject(source);
float[] lats = new float[latlons.length / 2];
float[] lons = new float[latlons.length / 2];
for (int i = 0; i < lats.length; i++) {
int index = i * 2;
lons[i] = latlons[index];
lats[i] = latlons[index + 1];
}
LatLonWrapper wrapper = new LatLonWrapper(lats, lons);
return wrapper;
}
}

View file

@ -0,0 +1,67 @@
/**
* 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.geospatial;
/**
* Lat/Lon data can be wrapped in here for ease of retrieval
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 21, 2013 mnash Initial creation
*
* </pre>
*
* @author mnash
* @version 1.0
*/
public class LatLonWrapper {
private float[] lats;
private float[] lons;
/**
*
*/
public LatLonWrapper(float[] lats, float[] lons) {
this.lats = lats;
this.lons = lons;
}
/**
* @return the lats
*/
public float[] getLats() {
return lats;
}
/**
* @return the lons
*/
public float[] getLons() {
return lons;
}
}

View file

@ -1,4 +1,4 @@
## # #
# This software was developed and / or modified by Raytheon Company, # This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government. # pursuant to Contract DG133W-05-CQ-1067 with the US Government.
# #
@ -16,7 +16,7 @@
# #
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for # See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information. # further licensing information.
## # #
# #
@ -39,7 +39,7 @@ if sys.modules.has_key('jep'):
import JepRouter import JepRouter
router = JepRouter router = JepRouter
else: else:
#router = ThriftClientRouter() # router = ThriftClientRouter()
import exceptions import exceptions
raise exceptions.NotImplementedError("Must use inside a JVM until ThriftClient support is added") raise exceptions.NotImplementedError("Must use inside a JVM until ThriftClient support is added")
@ -50,14 +50,11 @@ def getAvailableTimes(request):
def getData(request, times): def getData(request, times):
return router.getData(request, times) return router.getData(request, times)
def getLatCoords(gridRequest): def getLatLonCoords(gridRequest):
return router.getLatCoords(gridRequest) return router.getLatLonCoords(gridRequest)
def getLonCoords(gridRequest):
return router.getLonCoords(gridRequest)
def getAvailableLocationNames(geometryRequest): def getAvailableLocationNames(geometryRequest):
return router.getAvailableLocaitonNames(geometryRequest) return router.getAvailableLocationNames(geometryRequest)
def newGeometryRequest(): def newGeometryRequest():
return router.newGeometryRequest() return router.newGeometryRequest()