Omaha #5916 Exclude LatLon from initial DAF response for grid data.

This commit is contained in:
Ben Steffensmeier 2016-10-10 16:44:03 -05:00 committed by mjames-upc
parent 162dd5627b
commit 11c55078f9
13 changed files with 319 additions and 35 deletions

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Data Access Framework EDEX
Bundle-SymbolicName: com.raytheon.uf.edex.dataaccess
Bundle-Version: 1.14.0.qualifier
Bundle-Version: 1.16.0.qualifier
Bundle-Vendor: RAYTHEON
Require-Bundle: com.raytheon.uf.common.dataaccess,
com.raytheon.uf.common.serialization.comm,

View file

@ -83,6 +83,14 @@
<constructor-arg ref="getGridDataHandler" />
</bean>
<bean id="getGridLatLonHandler"
class="com.raytheon.uf.edex.dataaccess.handler.GetGridLatLonHandler" />
<bean factory-bean="handlerRegistry" factory-method="register">
<constructor-arg
value="com.raytheon.uf.common.dataaccess.request.GetGridLatLonRequest" />
<constructor-arg ref="getGridLatLonHandler" />
</bean>
<bean id="getNotificationFilterHandler"
class="com.raytheon.uf.edex.dataaccess.handler.GetNotificationFilterHandler" />
<bean factory-bean="handlerRegistry" factory-method="register">

View file

@ -39,24 +39,16 @@ import com.raytheon.uf.common.util.CollectionUtil;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 4, 2013 dgilling Initial creation
* Jun 4, 2013 dgilling Initial creation
* Oct 18, 2016 5916 bsteffen Allow lazy loading of lat/lon data
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public final class GetGridDataHandler implements
IRequestHandler<GetGridDataRequest> {
/*
* (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;
}
}

View file

@ -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}.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- --------- -----------------
* Oct 18, 2016 5916 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
*/
public final class GetGridLatLonHandler
implements IRequestHandler<GetGridLatLonRequest> {
@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;
}
}

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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):