{
- /*
- * (non-Javadoc)
- *
- * @see
- * com.raytheon.uf.common.serialization.comm.IRequestHandler#handleRequest
- * (com.raytheon.uf.common.serialization.comm.IServerRequest)
- */
@Override
public GetGridDataResponse handleRequest(final GetGridDataRequest request)
throws Exception {
@@ -73,7 +65,7 @@ public final class GetGridDataHandler implements
}
GetGridDataResponse response = new GetGridDataResponse(
- Arrays.asList(gridData));
+ Arrays.asList(gridData), request.isIncludeLatLonData());
return response;
}
}
diff --git a/edexOsgi/com.raytheon.uf.edex.dataaccess/src/com/raytheon/uf/edex/dataaccess/handler/GetGridLatLonHandler.java b/edexOsgi/com.raytheon.uf.edex.dataaccess/src/com/raytheon/uf/edex/dataaccess/handler/GetGridLatLonHandler.java
new file mode 100644
index 0000000000..502e72e37a
--- /dev/null
+++ b/edexOsgi/com.raytheon.uf.edex.dataaccess/src/com/raytheon/uf/edex/dataaccess/handler/GetGridLatLonHandler.java
@@ -0,0 +1,70 @@
+/**
+ * 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.dataaccess.handler;
+
+import org.geotools.coverage.grid.GridEnvelope2D;
+import org.geotools.coverage.grid.GridGeometry2D;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.referencing.CRS;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.FactoryException;
+
+import com.raytheon.uf.common.dataaccess.request.GetGridLatLonRequest;
+import com.raytheon.uf.common.dataaccess.response.GetGridLatLonResponse;
+import com.raytheon.uf.common.geospatial.LatLonReprojection;
+import com.raytheon.uf.common.geospatial.LatLonWrapper;
+import com.raytheon.uf.common.serialization.comm.IRequestHandler;
+
+/**
+ *
+ * Handler for {@link GetGridLatLonRequest}.
+ *
+ *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date Ticket# Engineer Description
+ * ------------- -------- --------- -----------------
+ * Oct 18, 2016 5916 bsteffen Initial creation
+ *
+ *
+ *
+ * @author bsteffen
+ */
+public final class GetGridLatLonHandler
+ implements IRequestHandler {
+
+ @Override
+ public GetGridLatLonResponse handleRequest(GetGridLatLonRequest request)
+ throws MismatchedDimensionException, FactoryException {
+ GridEnvelope2D range = new GridEnvelope2D(0, 0, request.getNx(),
+ request.getNy());
+ ReferencedEnvelope envelope = new ReferencedEnvelope(
+ request.getEnvelope(), CRS.parseWKT(request.getCrsWkt()));
+ GridGeometry2D gridGeometry = new GridGeometry2D(range, envelope);
+ GetGridLatLonResponse response = new GetGridLatLonResponse();
+ LatLonWrapper latLonData = LatLonReprojection.getLatLons(gridGeometry);
+ response.setNx(request.getNx());
+ response.setNy(request.getNy());
+ response.setLats(latLonData.getLats());
+ response.setLons(latLonData.getLons());
+ return response;
+ }
+}
diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/request/GetGridDataRequest.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/request/GetGridDataRequest.py
index e580807ebf..1859526523 100644
--- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/request/GetGridDataRequest.py
+++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/request/GetGridDataRequest.py
@@ -27,6 +27,7 @@
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 05/28/13 #2023 dgilling Initial Creation.
+# 05/28/13 #5916 bsteffen Add includeLatLonData
#
#
@@ -39,6 +40,7 @@ class GetGridDataRequest(AbstractDataAccessRequest):
super(GetGridDataRequest, self).__init__()
self.requestedTimes = None
self.requestedPeriod = None
+ self.includeLatLonData = True
def getRequestedTimes(self):
return self.requestedTimes
@@ -51,3 +53,9 @@ class GetGridDataRequest(AbstractDataAccessRequest):
def setRequestedPeriod(self, requestedPeriod):
self.requestedPeriod = requestedPeriod
+
+ def getIncludeLatLonData(self):
+ return self.includeLatLonData
+
+ def setIncludeLatLonData(self, includeLatLonData):
+ self.includeLatLonData = includeLatLonData;
\ No newline at end of file
diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/request/GetGridLatLonRequest.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/request/GetGridLatLonRequest.py
new file mode 100644
index 0000000000..ea50e96bce
--- /dev/null
+++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/request/GetGridLatLonRequest.py
@@ -0,0 +1,60 @@
+##
+# 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.
+##
+
+# File auto-generated against equivalent DynamicSerialize Java class
+#
+# SOFTWARE HISTORY
+#
+# Date Ticket# Engineer Description
+# ------------ ---------- ----------- --------------------------
+# Oct 10, 2016 5916 bsteffen Generated
+
+class GetGridLatLonRequest(object):
+
+ def __init__(self):
+ self.envelope = None
+ self.crsWkt = None
+ self.nx = None
+ self.ny = None
+
+ def getEnvelope(self):
+ return self.envelope
+
+ def setEnvelope(self, envelope):
+ self.envelope = envelope
+
+ def getCrsWkt(self):
+ return self.crsWkt
+
+ def setCrsWkt(self, crsWkt):
+ self.crsWkt = crsWkt
+
+ def getNx(self):
+ return self.nx
+
+ def setNx(self, nx):
+ self.nx = nx
+
+ def getNy(self):
+ return self.ny
+
+ def setNy(self, ny):
+ self.ny = ny
+
diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/request/__init__.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/request/__init__.py
index 7b8ddbdace..6d07ea53fb 100644
--- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/request/__init__.py
+++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/request/__init__.py
@@ -29,11 +29,12 @@ __all__ = [
'GetAvailableTimesRequest',
'GetGeometryDataRequest',
'GetGridDataRequest',
+ 'GetGridLatLonRequest',
+ 'GetIdentifierValuesRequest',
'GetNotificationFilterRequest',
- 'GetRequiredIdentifiersRequest',
- 'GetSupportedDatatypesRequest',
'GetOptionalIdentifiersRequest',
- 'GetIdentifierValuesRequest'
+ 'GetRequiredIdentifiersRequest',
+ 'GetSupportedDatatypesRequest'
]
from AbstractDataAccessRequest import AbstractDataAccessRequest
@@ -44,8 +45,10 @@ from GetAvailableParametersRequest import GetAvailableParametersRequest
from GetAvailableTimesRequest import GetAvailableTimesRequest
from GetGeometryDataRequest import GetGeometryDataRequest
from GetGridDataRequest import GetGridDataRequest
+from GetGridLatLonRequest import GetGridLatLonRequest
+from GetIdentifierValuesRequest import GetIdentifierValuesRequest
from GetNotificationFilterRequest import GetNotificationFilterRequest
+from GetOptionalIdentifiersRequest import GetOptionalIdentifiersRequest
from GetRequiredIdentifiersRequest import GetRequiredIdentifiersRequest
from GetSupportedDatatypesRequest import GetSupportedDatatypesRequest
-from GetOptionalIdentifiersRequest import GetOptionalIdentifiersRequest
-from GetIdentifierValuesRequest import GetIdentifierValuesRequest
+
diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/GetGridDataResponse.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/GetGridDataResponse.py
index 0e2544aec9..665f57c1e4 100644
--- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/GetGridDataResponse.py
+++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/GetGridDataResponse.py
@@ -28,6 +28,8 @@ class GetGridDataResponse(object):
self.siteNyValues = None
self.siteLatGrids = None
self.siteLonGrids = None
+ self.siteEnvelopes = None
+ self.siteCrsWkt = None
def getGridData(self):
return self.gridData
@@ -59,3 +61,15 @@ class GetGridDataResponse(object):
def setSiteLonGrids(self, siteLonGrids):
self.siteLonGrids = siteLonGrids
+ def getSiteEnvelopes(self):
+ return self.siteEnvelopes
+
+ def setSiteEnvelopes(self, siteEnvelopes):
+ self.siteEnvelopes = siteEnvelopes
+
+ def getSiteCrsWkt(self):
+ return self.siteCrsWkt
+
+ def setSiteCrsWkt(self, siteCrsWkt):
+ self.siteCrsWkt = siteCrsWkt
+
diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/GetGridLatLonResponse.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/GetGridLatLonResponse.py
new file mode 100644
index 0000000000..f86f4c30b0
--- /dev/null
+++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/GetGridLatLonResponse.py
@@ -0,0 +1,60 @@
+##
+# 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.
+##
+
+# File auto-generated against equivalent DynamicSerialize Java class
+#
+# SOFTWARE HISTORY
+#
+# Date Ticket# Engineer Description
+# ------------ ---------- ----------- --------------------------
+# Oct 10, 2016 5916 bsteffen Generated
+
+class GetGridLatLonResponse(object):
+
+ def __init__(self):
+ self.lats = None
+ self.lons = None
+ self.nx = None
+ self.ny = None
+
+ def getLats(self):
+ return self.lats
+
+ def setLats(self, lats):
+ self.lats = lats
+
+ def getLons(self):
+ return self.lons
+
+ def setLons(self, lons):
+ self.lons = lons
+
+ def getNx(self):
+ return self.nx
+
+ def setNx(self, nx):
+ self.nx = nx
+
+ def getNy(self):
+ return self.ny
+
+ def setNy(self, ny):
+ self.ny = ny
+
diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/__init__.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/__init__.py
index e9eb1660b8..6a0dd92642 100644
--- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/__init__.py
+++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/__init__.py
@@ -25,13 +25,16 @@ __all__ = [
'GeometryResponseData',
'GetGeometryDataResponse',
'GetGridDataResponse',
- 'GridResponseData',
- 'GetNotificationFilterResponse'
+ 'GetGridLatLonResponse',
+ 'GetNotificationFilterResponse',
+ 'GridResponseData'
]
from AbstractResponseData import AbstractResponseData
from GeometryResponseData import GeometryResponseData
from GetGeometryDataResponse import GetGeometryDataResponse
from GetGridDataResponse import GetGridDataResponse
+from GetGridLatLonResponse import GetGridLatLonResponse
+from GetNotificationFilterResponse import GetNotificationFilterResponse
from GridResponseData import GridResponseData
-from GetNotificationFilterResponse import GetNotificationFilterResponse
\ No newline at end of file
+
diff --git a/pythonPackages/ufpy/dataaccess/DataAccessLayer.py b/pythonPackages/ufpy/dataaccess/DataAccessLayer.py
index 5a22ddf61b..f93c4925c2 100644
--- a/pythonPackages/ufpy/dataaccess/DataAccessLayer.py
+++ b/pythonPackages/ufpy/dataaccess/DataAccessLayer.py
@@ -40,7 +40,7 @@
# Jun 01, 2016 5587 tgurney Add new signatures for
# getRequiredIdentifiers() and
# getOptionalIdentifiers()
-#
+# Oct 18, 2016 5916 bsteffen Add setLazyLoadGridLatLon
#
#
@@ -251,3 +251,26 @@ def changeEDEXHost(newHostName):
router = ThriftClientRouter.ThriftClientRouter(THRIFT_HOST)
else:
raise TypeError("Cannot call changeEDEXHost when using JepRouter.")
+
+def setLazyLoadGridLatLon(lazyLoadGridLatLon):
+ """
+ Provide a hint to the Data Access Framework indicating whether to load the
+ lat/lon data for a grid immediately or wait until it is needed. This is
+ provided as a performance tuning hint and should not affect the way the
+ Data Access Framework is used. Depending on the internal implementation of
+ the Data Access Framework this hint might be ignored. Examples of when this
+ should be set to True are when the lat/lon information is not used or when
+ it is used only if certain conditions within the data are met. It could be
+ set to False if it is guaranteed that all lat/lon information is needed and
+ it would be better to get any performance overhead for generating the
+ lat/lon data out of the way during the initial request.
+
+
+ Args:
+ lazyLoadGridLatLon: Boolean value indicating whether to lazy load.
+ """
+ try:
+ router.setLazyLoadGridLatLon(lazyLoadGridLatLon)
+ except AttributeError:
+ # The router is not required to support this capability.
+ pass
\ No newline at end of file
diff --git a/pythonPackages/ufpy/dataaccess/PyGridData.py b/pythonPackages/ufpy/dataaccess/PyGridData.py
index ab6c5e5600..d573ec966d 100644
--- a/pythonPackages/ufpy/dataaccess/PyGridData.py
+++ b/pythonPackages/ufpy/dataaccess/PyGridData.py
@@ -28,7 +28,8 @@
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 06/03/13 #2023 dgilling Initial Creation.
-# 11/10/16 #5900 bsteffen Correct grid shape
+# 10/13/16 #5916 bsteffen Correct grid shape, allow lat/lon
+# to be requested by a delegate
#
#
@@ -36,8 +37,8 @@
import numpy
import warnings
-from awips.dataaccess import IGridData
-from awips.dataaccess import PyData
+from ufpy.dataaccess import IGridData
+from ufpy.dataaccess import PyData
NO_UNIT_CONVERT_WARNING = """
The ability to unit convert grid data is not currently available in this version of the Data Access Framework.
@@ -46,7 +47,7 @@ The ability to unit convert grid data is not currently available in this version
class PyGridData(IGridData, PyData.PyData):
- def __init__(self, gridDataRecord, nx, ny, latLonGrid):
+ def __init__(self, gridDataRecord, nx, ny, latLonGrid = None, latLonDelegate = None):
PyData.PyData.__init__(self, gridDataRecord)
nx = nx
ny = ny
@@ -54,6 +55,8 @@ class PyGridData(IGridData, PyData.PyData):
self.__unit = gridDataRecord.getUnit()
self.__gridData = numpy.reshape(numpy.array(gridDataRecord.getGridData()), (ny, nx))
self.__latLonGrid = latLonGrid
+ self.__latLonDelegate = latLonDelegate
+
def getParameter(self):
return self.__parameter
@@ -70,4 +73,8 @@ class PyGridData(IGridData, PyData.PyData):
return self.__gridData
def getLatLonCoords(self):
+ if self.__latLonGrid is not None:
+ return self.__latLonGrid
+ elif self.__latLonDelegate is not None:
+ return self.__latLonDelegate()
return self.__latLonGrid
diff --git a/pythonPackages/ufpy/dataaccess/ThriftClientRouter.py b/pythonPackages/ufpy/dataaccess/ThriftClientRouter.py
index 182d0eb6e3..64fc8f3e6e 100644
--- a/pythonPackages/ufpy/dataaccess/ThriftClientRouter.py
+++ b/pythonPackages/ufpy/dataaccess/ThriftClientRouter.py
@@ -39,7 +39,7 @@
# getRequiredIdentifiers() and
# getOptionalIdentifiers()
# 08/01/16 2416 tgurney Add getNotificationFilter()
-# 11/10/16 5900 bsteffen Correct grid shape
+# 10/13/16 5916 bsteffen Correct grid shape, allow lazy grid lat/lon
#
@@ -51,6 +51,7 @@ from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import G
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetAvailableTimesRequest
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetGeometryDataRequest
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetGridDataRequest
+from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetGridLatLonRequest
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetAvailableParametersRequest
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetAvailableLevelsRequest
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetRequiredIdentifiersRequest
@@ -59,16 +60,42 @@ from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import G
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetSupportedDatatypesRequest
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetNotificationFilterRequest
-from awips import ThriftClient
-from awips.dataaccess import PyGeometryData
-from awips.dataaccess import PyGridData
+from ufpy import ThriftClient
+from ufpy.dataaccess import PyGeometryData
+from ufpy.dataaccess import PyGridData
+class LazyGridLatLon(object):
+ def __init__(self, client, nx, ny, envelope, crsWkt):
+ self._latLonGrid = None
+ self._client = client
+ self._request = GetGridLatLonRequest()
+ self._request.setNx(nx);
+ self._request.setNy(ny);
+ self._request.setEnvelope(envelope);
+ self._request.setCrsWkt(crsWkt);
+ def __call__(self):
+ # Its important that the data is cached internally so that if multiple
+ # GridData are sharing the same delegate then they can also share a
+ # single request for the LatLon information.
+ if self._latLonGrid is None:
+ response = self._client.sendRequest(self._request)
+ nx = response.getNx()
+ ny = response.getNy()
+ latData = numpy.reshape(numpy.array(response.getLats()), (ny, nx))
+ lonData = numpy.reshape(numpy.array(response.getLons()), (ny, nx))
+ self._latLonGrid = (lonData, latData)
+ return self._latLonGrid
+
class ThriftClientRouter(object):
def __init__(self, host='localhost'):
self._client = ThriftClient.ThriftClient(host)
-
+ self._lazyLoadGridLatLon = False
+
+ def setLazyLoadGridLatLon(self, lazyLoadGridLatLon):
+ self._lazyLoadGridLatLon = lazyLoadGridLatLon
+
def getAvailableTimes(self, request, refTimeOnly):
timesRequest = GetAvailableTimesRequest()
timesRequest.setRequestParameters(request)
@@ -78,6 +105,7 @@ class ThriftClientRouter(object):
def getGridData(self, request, times):
gridDataRequest = GetGridDataRequest()
+ gridDataRequest.setIncludeLatLonData(not self._lazyLoadGridLatLon)
gridDataRequest.setRequestParameters(request)
# if we have an iterable times instance, then the user must have asked
# for grid data with the List of DataTime objects
@@ -95,15 +123,23 @@ class ThriftClientRouter(object):
for location in locNames:
nx = response.getSiteNxValues()[location]
ny = response.getSiteNyValues()[location]
- latData = numpy.reshape(numpy.array(response.getSiteLatGrids()[location]), (ny, nx))
- lonData = numpy.reshape(numpy.array(response.getSiteLonGrids()[location]), (ny, nx))
- locSpecificData[location] = (nx, ny, (lonData, latData))
-
+ if self._lazyLoadGridLatLon:
+ envelope = response.getSiteEnvelopes()[location]
+ crsWkt = response.getSiteCrsWkt()[location]
+ delegate = LazyGridLatLon(self._client, nx, ny, envelope, crsWkt)
+ locSpecificData[location] = (nx, ny, delegate)
+ else:
+ latData = numpy.reshape(numpy.array(response.getSiteLatGrids()[location]), (ny, nx))
+ lonData = numpy.reshape(numpy.array(response.getSiteLonGrids()[location]), (ny, nx))
+ locSpecificData[location] = (nx, ny, (lonData, latData))
retVal = []
for gridDataRecord in response.getGridData():
locationName = gridDataRecord.getLocationName()
locData = locSpecificData[locationName]
- retVal.append(PyGridData.PyGridData(gridDataRecord, locData[0], locData[1], locData[2]))
+ if self._lazyLoadGridLatLon:
+ retVal.append(PyGridData.PyGridData(gridDataRecord, locData[0], locData[1], latLonDelegate=locData[2]))
+ else:
+ retVal.append(PyGridData.PyGridData(gridDataRecord, locData[0], locData[1], locData[2]))
return retVal
def getGeometryData(self, request, times):