diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/python/dataaccess/JGridData.py b/edexOsgi/build.edex/esb/data/utility/common_static/base/python/dataaccess/JGridData.py index 21286cbb7a..9d6be0e175 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/python/dataaccess/JGridData.py +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/python/dataaccess/JGridData.py @@ -69,10 +69,14 @@ class JGridData(IGridData, JData.JData): unitObj = UnitFormat.getUCUMInstance().parseObject(unit) converter = self.jobj.getUnit().getConverterTo(unitObj) unitDest = UnitConvertingDataDestination(converter, dest) - filledDest = self.jobj.populateDataDestination(unitDest) - pnfa = PythonNumpyFloatArray(filledDest.getWrappedDestination().getFloatArray()) + filledDest = self.jobj.populateData(unitDest) + nx = self.jobj.getGridGeometry().getGridRange().getSpan(0) + ny = self.jobj.getGridGeometry().getGridRange().getSpan(1) + pnfa = PythonNumpyFloatArray(filledDest.getWrappedDestination().getArray(), nx, ny) else: - filledDest = self.jobj.populateDataDestination(dest) - pnfa = PythonNumpyFloatArray(dest.getFloatArray()) + filledDest = self.jobj.populateData(dest) + nx = self.jobj.getGridGeometry().getGridRange().getSpan(0); + ny = self.jobj.getGridGeometry().getGridRange().getSpan(1); + pnfa = PythonNumpyFloatArray(dest.getArray(), nx, ny) return pnfa.__numpy__[0] diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/python/dataaccess/JepRouter.py b/edexOsgi/build.edex/esb/data/utility/common_static/base/python/dataaccess/JepRouter.py index 2ea5111641..8d03315b5b 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/python/dataaccess/JepRouter.py +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/python/dataaccess/JepRouter.py @@ -1,4 +1,4 @@ -## +# # # This software was developed and / or modified by Raytheon Company, # 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 # 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.impl import DefaultGridRequest, DefaultGeometryRequest 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 DataTime @@ -73,15 +75,17 @@ def getData(request, times): data.append(wrapper(jd)) return data -def getLatCoords(gridRequest): - # TODO need to request the GridGeometry, then translate it into lat/lons - # Ben has ideas about how to do this fast - pass - -def getLonCoords(gridRequest): - # TODO need to request the GridGeometry, then translate it into lat/lons - # Ben has ideas about how to do this fast - pass +def getLatLonCoords(gridRequest): + ''' + @return: a tuple where the first element is a numpy array of lons, and the second element is a numpy array of lats + ''' + gridGeometry = JavaDataAccessLayer.getGridGeometry(gridRequest.toJavaObj()) + latlons = LatLonReprojection.getLatLons(gridGeometry) + nx = gridGeometry.getGridRange().getSpan(0) + ny = gridGeometry.getGridRange().getSpan(1) + latndarray = PythonNumpyFloatArray(latlons.getLats(), nx, ny).__numpy__[0] + lonndarray = PythonNumpyFloatArray(latlons.getLons(), nx, ny).__numpy__[0] + return (lonndarray, latndarray) def getAvailableLocationNames(geometryRequest): return JavaDataAccessLayer.getAvailableLocationNames(geometryRequest.toJavaObj()) diff --git a/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/LatLonReprojection.java b/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/LatLonReprojection.java new file mode 100644 index 0000000000..3cddf2bef8 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/LatLonReprojection.java @@ -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 + * + *
+ * + * SOFTWARE HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * Jan 15, 2013 mnash Initial creation + * + *+ * + * @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; + } +} diff --git a/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/LatLonWrapper.java b/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/LatLonWrapper.java new file mode 100644 index 0000000000..70b898e9e1 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/LatLonWrapper.java @@ -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 + * + *
+ * + * SOFTWARE HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * Jan 21, 2013 mnash Initial creation + * + *+ * + * @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; + } + +} diff --git a/pythonPackages/ufpy/dataaccess/DataAccessLayer.py b/pythonPackages/ufpy/dataaccess/DataAccessLayer.py index 76ba9b5b43..846f2112be 100644 --- a/pythonPackages/ufpy/dataaccess/DataAccessLayer.py +++ b/pythonPackages/ufpy/dataaccess/DataAccessLayer.py @@ -1,4 +1,4 @@ -## +# # # This software was developed and / or modified by Raytheon Company, # 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 # further licensing information. -## +# # # @@ -39,7 +39,7 @@ if sys.modules.has_key('jep'): import JepRouter router = JepRouter else: - #router = ThriftClientRouter() + # router = ThriftClientRouter() import exceptions raise exceptions.NotImplementedError("Must use inside a JVM until ThriftClient support is added") @@ -50,14 +50,11 @@ def getAvailableTimes(request): def getData(request, times): return router.getData(request, times) -def getLatCoords(gridRequest): - return router.getLatCoords(gridRequest) - -def getLonCoords(gridRequest): - return router.getLonCoords(gridRequest) +def getLatLonCoords(gridRequest): + return router.getLatLonCoords(gridRequest) def getAvailableLocationNames(geometryRequest): - return router.getAvailableLocaitonNames(geometryRequest) + return router.getAvailableLocationNames(geometryRequest) def newGeometryRequest(): return router.newGeometryRequest()