Issue #1614 allow locationNames for grid data access

Change-Id: I5d88708909b8f76ebdf6fac64a330854781ffae2

Former-commit-id: 9b4de367e3 [formerly ef7addb005 [formerly ab319bd3a8] [formerly 9b4de367e3 [formerly 7fe101c9fdb9266cd7c16a6c0a7281b9f9836cc4]]]
Former-commit-id: ef7addb005 [formerly ab319bd3a8]
Former-commit-id: ef7addb005
Former-commit-id: 31605a14aa
This commit is contained in:
Ben Steffensmeier 2013-02-11 15:10:40 -06:00 committed by Gerrit Code Review
parent d38eeb2b40
commit 46b14eb23e
25 changed files with 235 additions and 119 deletions

View file

@ -170,6 +170,10 @@ public class GenericGridResource extends
StringBuilder stringBuilder = new StringBuilder();
if (gridData.getLocationName() != null) {
stringBuilder.append(gridData.getLocationName());
stringBuilder.append(_SPACE_);
}
if (gridData.getParameter() != null) {
stringBuilder.append(gridData.getParameter());
stringBuilder.append(_SPACE_);

View file

@ -49,6 +49,9 @@ class JData(IData, JUtil.JavaWrapperClass):
def getLevel(self):
return str(self.jobj.getLevel())
def getLocationName(self):
return self.jobj.getLocationName()
def toJavaObj(self):
return self.jobj

View file

@ -61,6 +61,9 @@ class JDataRequest(IDataRequest, JUtil.JavaWrapperClass):
levels[i] = Level(str(args[i]))
self.jobj.setLevels(levels)
def getLocationNames(self):
return self.jobj.getLocationNames()
def getDatatype(self):
return self.jobj.getDatatype()
@ -84,6 +87,13 @@ class JDataRequest(IDataRequest, JUtil.JavaWrapperClass):
levels.append(str(lev))
return levels
def setLocationNames(self, *args):
from java.lang import String as JavaString
locs = jep.jarray(len(args), JavaString)
for i in xrange(len(args)):
locs[i] = str(args[i])
self.jobj.setLocationNames(locs)
def toJavaObj(self):
return self.jobj

View file

@ -93,6 +93,3 @@ class JGeometryData(IGeometryData, JData.JData):
def getType(self, param):
return str(self.jobj.getType(param))
def getLocationName(self):
return self.jobj.getLocationName()

View file

@ -54,15 +54,5 @@ class JGeometryRequest(IGeometryRequest, JDataRequest.JDataRequest):
from com.vividsolutions.jts.geom import Envelope
bounds = env.bounds
jenv = Envelope(bounds[0], bounds[2], bounds[1], bounds[3])
self.jobj.setEnvelope(bounds)
def getLocationNames(self):
return self.jobj.getLocationNames()
def setLocationNames(self, *args):
from java.lang import String as JavaString
locs = jep.jarray(len(args), JavaString)
for i in xrange(len(args)):
locs[i] = str(args[i])
self.jobj.setLocationNames(locs)
self.jobj.setEnvelope(bounds)

View file

@ -89,8 +89,8 @@ def getLatLonCoords(gridRequest):
lonndarray = PythonNumpyFloatArray(latlons.getLons(), nx, ny).__numpy__[0]
return (lonndarray, latndarray)
def getAvailableLocationNames(geometryRequest):
return JavaDataAccessLayer.getAvailableLocationNames(geometryRequest.toJavaObj())
def getAvailableLocationNames(request):
return JavaDataAccessLayer.getAvailableLocationNames(request.toJavaObj())
def newGeometryRequest():
return JGeometryRequest.JGeometryRequest(DefaultGeometryRequest())

View file

@ -23,8 +23,6 @@ import org.geotools.coverage.grid.GridGeometry2D;
import com.raytheon.uf.common.dataaccess.exception.DataFactoryNotFoundException;
import com.raytheon.uf.common.dataaccess.exception.TimeAgnosticDataException;
import com.raytheon.uf.common.dataaccess.geom.IGeometryDataFactory;
import com.raytheon.uf.common.dataaccess.geom.IGeometryRequest;
import com.raytheon.uf.common.dataaccess.grid.IGridDataFactory;
import com.raytheon.uf.common.dataaccess.grid.IGridRequest;
import com.raytheon.uf.common.time.BinOffset;
@ -143,8 +141,9 @@ public class DataAccessLayer {
* @param request
* @return the available location names if the data was requested
*/
public static String[] getAvailableLocationNames(IGeometryRequest request) {
IGeometryDataFactory factory = (IGeometryDataFactory) getFactory(request);
public static <R extends IDataRequest<D>, D extends IData> String[] getAvailableLocationNames(
R request) {
IDataFactory<R, D> factory = getFactory(request);
return factory.getAvailableLocationNames(request);
}

View file

@ -64,4 +64,12 @@ public interface IData {
*/
public Level getLevel();
/**
* Gets the location name associated with this instance of IData. May be
* null.
*
* @return the location name or null
*/
public String getLocationName();
}

View file

@ -113,4 +113,15 @@ public interface IDataFactory<R extends IDataRequest<D>, D extends IData> {
*/
public D[] getData(R request, TimeRange timeRange);
/**
* Gets the available location names that match the request. Implementations
* should throw LocationNameUnsupportedException if location names do not
* apply to their datatype.
*
* @param request
* the request to find matching location names for
* @return the available location names that match the request
*/
public String[] getAvailableLocationNames(R request);
}

View file

@ -82,6 +82,19 @@ public interface IDataRequest<D extends IData> {
*/
public void setLevels(Level... levels);
/**
* Sets a list of location names to limit what is returned. Each datatype
* may have its own mapping of what a location is (e.g. ICAO vs stationId vs
* radar name, etc). Possible location names can be retrieved by using the
* method getAvailableLocationNames(IGeometryRequest) on the DataAccessLayer
* or IGeometryDataFactory. Note that not all factories may support requests
* by location names and instead may throw a
* LocationNameUnsupportedException or ignore the location names.
*
* @param locationNames
*/
public void setLocationNames(String... locationNames);
/**
* Returns the datatype set on the request.
*
@ -110,4 +123,11 @@ public interface IDataRequest<D extends IData> {
*/
public Level[] getLevels();
/**
* Returns the location names set on the request.
*
* @return
*/
public String[] getLocationNames();
}

View file

@ -118,12 +118,5 @@ public interface IGeometryData extends IData {
*/
public Type getType(String param);
/**
* Gets the location name associated with this instance of IData. May be
* null.
*
* @return the location name or null
*/
public String getLocationName();
}

View file

@ -42,15 +42,4 @@ import com.raytheon.uf.common.dataaccess.IDataFactory;
public interface IGeometryDataFactory extends
IDataFactory<IGeometryRequest, IGeometryData> {
/**
* Gets the available location names that match the request. Implementations
* should throw LocationNameUnsupportedException if location names do not
* apply to their datatype.
*
* @param request
* the request to find matching location names for
* @return the available location names that match the request
*/
public String[] getAvailableLocationNames(IGeometryRequest request);
}

View file

@ -60,24 +60,4 @@ public interface IGeometryRequest extends IDataRequest<IGeometryData> {
*/
public Envelope getEnvelope();
/**
* Sets a list of location names to limit what is returned. Each datatype
* may have its own mapping of what a location is (e.g. ICAO vs stationId vs
* radar name, etc). Possible location names can be retrieved by using the
* method getAvailableLocationNames(IGeometryRequest) on the DataAccessLayer
* or IGeometryDataFactory. Note that not all factories may support requests
* by location names and instead may throw a
* LocationNameUnsupportedException or ignore the location names.
*
* @param locationNames
*/
public void setLocationNames(String... locationNames);
/**
* Returns the location names set on the request.
*
* @return
*/
public String[] getLocationNames();
}

View file

@ -130,6 +130,20 @@ public abstract class AbstractDataPluginFactory<R extends IDataRequest<D>, D ext
return getData(request, dbQueryResponse);
}
public String[] getAvailableLocationNames(R request, String locationColumn) {
DbQueryRequest dbQueryRequest = buildDbQueryRequest(request);
dbQueryRequest.setDistinct(Boolean.TRUE);
dbQueryRequest.addRequestField(locationColumn);
DbQueryResponse dbQueryResponse = this.executeDbQueryRequest(
dbQueryRequest, request.toString());
List<String> locationNames = new ArrayList<String>();
for (Map<String, Object> result : dbQueryResponse.getResults()) {
locationNames.add(result.get(locationColumn).toString());
}
return locationNames.toArray(new String[0]);
}
/**
* Executes the provided DbQueryRequest and returns a DbQueryResponse
*

View file

@ -19,12 +19,13 @@
**/
package com.raytheon.uf.common.dataaccess.impl;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.HashMap;
import java.util.Map;
import com.raytheon.uf.common.dataplugin.level.Level;
import com.raytheon.uf.common.serialization.XmlGenericMapAdapter;
@ -62,6 +63,9 @@ public abstract class AbstractDataRequest {
@XmlElement
protected Level[] levels;
@XmlElement(name = "locationName")
protected String[] locationNames;
public void setDatatype(String datatype) {
this.datatype = datatype;
}
@ -97,4 +101,13 @@ public abstract class AbstractDataRequest {
return levels;
}
public void setLocationNames(String... locationNames) {
this.locationNames = locationNames;
}
public String[] getLocationNames() {
return locationNames;
}
}

View file

@ -122,6 +122,23 @@ public abstract class AbstractGridDataPluginFactory extends
return PDOUtil.retrieveGeometry(pdo);
}
/**
* Builds an IGridData with the information that is supplied
*
* @param request
* the original grid request
* @param pdo
* a record that was retrieved from the database
* @param gridGeometry
* the geometry extracted from the pdo
* @param dataRecord
* the raw data
* @return the IGridData that was constructed
*/
protected abstract IGridData constructGridDataResponse(
IGridRequest request, PluginDataObject pdo,
GridGeometry2D gridGeometry, IDataRecord dataRecord);
/**
* Given a full PDO grid geometry and the request used this will determine
* the geometry that describes the requested area. For null or ALL this
@ -136,7 +153,8 @@ public abstract class AbstractGridDataPluginFactory extends
* this will create a subset geometry describing the slab and for
* all other types of requests this returns null.
*/
protected GridGeometry2D trimGridGeometryToRequest(GridGeometry2D gridGeom,
protected static GridGeometry2D trimGridGeometryToRequest(
GridGeometry2D gridGeom,
Request storageRequest) {
if (storageRequest == null || storageRequest.getType() == Type.ALL) {
return gridGeom;
@ -161,21 +179,4 @@ public abstract class AbstractGridDataPluginFactory extends
}
}
/**
* Builds an IGridData with the information that is supplied
*
* @param request
* the original grid request
* @param pdo
* a record that was retrieved from the database
* @param gridGeometry
* the geometry extracted from the pdo
* @param dataRecord
* the raw data
* @return the IGridData that was constructed
*/
protected abstract IGridData constructGridDataResponse(
IGridRequest request, PluginDataObject pdo,
GridGeometry2D gridGeometry, IDataRecord dataRecord);
}

View file

@ -21,7 +21,6 @@ package com.raytheon.uf.common.dataaccess.impl;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.raytheon.uf.common.dataaccess.geom.IGeometryRequest;
@ -52,9 +51,6 @@ public class DefaultGeometryRequest extends AbstractDataRequest implements
@XmlJavaTypeAdapter(value = JTSEnvelopeAdapter.class)
protected Envelope envelope;
@XmlElement(name="locationName")
protected String[] locationNames;
@Override
public void setEnvelope(Envelope env) {
this.envelope = env;
@ -65,15 +61,4 @@ public class DefaultGeometryRequest extends AbstractDataRequest implements
return envelope;
}
@Override
public void setLocationNames(String... locationNames) {
this.locationNames = locationNames;
}
@Override
public String[] getLocationNames() {
return locationNames;
}
}

View file

@ -65,6 +65,8 @@ public class DefaultGridData implements IGridData {
protected Map<String, Object> attributes;
protected String locationName;
public DefaultGridData(DataSource data, GridGeometry2D gridGeometry) {
this.data = data;
this.gridGeometry = gridGeometry;
@ -104,6 +106,11 @@ public class DefaultGridData implements IGridData {
return unit;
}
@Override
public String getLocationName() {
return locationName;
}
@SuppressWarnings("unchecked")
@Override
public DataDestination populateData(DataDestination destination) {
@ -140,4 +147,8 @@ public class DefaultGridData implements IGridData {
this.attributes = attrs;
}
public void setLocationName(String locationName) {
this.locationName = locationName;
}
}

View file

@ -58,6 +58,8 @@ public class GFEDataAccessUtil {
public static final String PARM_ID = "parmId";
public static final String DB_ID = "dbId";
public static final String PLUGIN_NAME = "pluginName";
public static final String SITE_ID = "siteId";

View file

@ -19,9 +19,12 @@
**/
package com.raytheon.uf.common.dataplugin.gfe.dataaccess;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.geotools.coverage.grid.GridGeometry2D;
@ -33,6 +36,7 @@ import com.raytheon.uf.common.dataaccess.impl.AbstractGridDataPluginFactory;
import com.raytheon.uf.common.dataaccess.impl.DefaultGridData;
import com.raytheon.uf.common.dataaccess.util.DataWrapperUtil;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GFERecord;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridLocation;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridParmInfo;
@ -94,6 +98,7 @@ public class GFEGridFactory extends AbstractGridDataPluginFactory implements
level.setMasterLevel(new MasterLevel(gfeRecord.getParmLevel()));
defaultGridData.setLevel(level);
defaultGridData.setUnit(gfeRecord.getGridInfo().getUnitObject());
defaultGridData.setLocationName(gfeRecord.getDbId().getSiteId());
Map<String, Object> attrs = new HashMap<String, Object>();
attrs.put(GFEDataAccessUtil.MODEL_NAME, gfeRecord.getDbId()
@ -149,9 +154,34 @@ public class GFEGridFactory extends AbstractGridDataPluginFactory implements
}
}
constraints.put(GFEDataAccessUtil.PLUGIN_NAME, new RequestConstraint("gfe"));
constraints.put(GFEDataAccessUtil.PARM_ID,
GFEDataAccessUtil.createParmIdConstraint(parmIdComponents));
String[] locationNames = request.getLocationNames();
if (locationNames != null) {
if (locationNames.length == 1) {
parmIdComponents.put(GFEDataAccessUtil.SITE_ID,
locationNames[0]);
} else if (locationNames.length > 1) {
RequestConstraint dbIdConstraint = new RequestConstraint(null,
ConstraintType.IN);
HashSet<String> locationNamesSet = new HashSet<String>(
Arrays.asList(locationNames));
DbQueryRequest dbRequest = new DbQueryRequest();
dbRequest.addRequestField(GFEDataAccessUtil.DB_ID);
dbRequest.setDistinct(true);
DbQueryResponse dbResonse = executeDbQueryRequest(dbRequest,
request.toString());
for (Map<String, Object> resultMap : dbResonse.getResults()) {
DatabaseID dbId = (DatabaseID) resultMap
.get(GFEDataAccessUtil.DB_ID);
if (locationNamesSet.contains(dbId.getSiteId())) {
dbIdConstraint
.addToConstraintValueList(dbId.toString());
}
}
constraints.put(GFEDataAccessUtil.DB_ID, dbIdConstraint);
}
}
return constraints;
}
@ -170,7 +200,7 @@ public class GFEGridFactory extends AbstractGridDataPluginFactory implements
// This also grabs vector data.
data = ((ScalarGridSlice) slice).getScalarGrid();
} else {
throw new DataRetrievalException("UNknown slice of type "
throw new DataRetrievalException("Unknown slice of type "
+ slice.getClass().getSimpleName());
}
return new FloatDataRecord("Data", gfeRecord.getDataURI(), data.getFloats(), 2, new long[] {
@ -208,6 +238,22 @@ public class GFEGridFactory extends AbstractGridDataPluginFactory implements
return null;
}
@Override
public String[] getAvailableLocationNames(IGridRequest request) {
DbQueryRequest dbRequest = buildDbQueryRequest(request);
dbRequest.addRequestField(GFEDataAccessUtil.DB_ID);
dbRequest.setDistinct(true);
DbQueryResponse dbResonse = executeDbQueryRequest(dbRequest,
request.toString());
Set<String> locationNames = new HashSet<String>();
for (Map<String, Object> resultMap : dbResonse.getResults()) {
DatabaseID dbId = (DatabaseID) resultMap
.get(GFEDataAccessUtil.DB_ID);
locationNames.add(dbId.getSiteId());
}
return locationNames.toArray(new String[0]);
}
private GFERecord asGFERecord(Object obj) {
if (obj instanceof GFERecord == false) {
throw new DataRetrievalException(this.getClass().getSimpleName()

View file

@ -160,6 +160,16 @@ public class GridDataAccessFactory extends AbstractGridDataPluginFactory
assembler.setLevelTwoValue(null);
}
if (request.getLocationNames() != null) {
for (String loc : request.getLocationNames()) {
assembler.setDatasetId(loc);
mergeConstraintMaps(assembler.getConstraintMap(), result);
}
// clear fields so it doesn't merge the last one again.
assembler.setDatasetId(null);
}
if (identifiers != null) {
if (identifiers.containsKey(GridConstants.DATASET_ID)) {
assembler.setDatasetId(identifiers.get(
@ -272,6 +282,7 @@ public class GridDataAccessFactory extends AbstractGridDataPluginFactory
defaultGridData.setDataTime(pdo.getDataTime());
defaultGridData.setParameter(parameter);
defaultGridData.setLevel(level);
defaultGridData.setLocationName(datasetId);
defaultGridData.setUnit(gridRecord.getParameter().getUnit());
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(GridConstants.DATASET_ID, datasetId);
@ -293,4 +304,10 @@ public class GridDataAccessFactory extends AbstractGridDataPluginFactory
return base;
}
@Override
public String[] getAvailableLocationNames(IGridRequest request) {
return getAvailableLocationNames(request, GridConstants.DATASET_ID);
}
}

View file

@ -147,8 +147,7 @@ public class RadarGridFactory extends AbstractGridDataPluginFactory implements
IDataRecord dataRecord) {
RadarRecord radarRecord = asRadarRecord(pdo);
DataWrapper1D wrapper = DataWrapperUtil.constructArrayWrapper(
dataRecord,
false);
dataRecord, false);
wrapper.setFillValue(0);
DataSource source = wrapper;
if (radarRecord.getFormat().equals(RADIAL_FORMAT)) {
@ -176,9 +175,9 @@ public class RadarGridFactory extends AbstractGridDataPluginFactory implements
defaultGridData.setUnit(radarRecord.getDataUnit());
defaultGridData.setLevel(getTiltLevel(radarRecord
.getPrimaryElevationAngle()));
defaultGridData.setLocationName(radarRecord.getIcao());
Map<String, Object> attributes = new HashMap<String, Object>(
request.getIdentifiers());
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(ICAO, radarRecord.getIcao());
attributes.put(FORMAT, radarRecord.getFormat());
@ -231,8 +230,7 @@ public class RadarGridFactory extends AbstractGridDataPluginFactory implements
Request storageRequest) {
RadarRecord radarRecord = asRadarRecord(pdo);
try {
RadarDataRetriever.populateRadarRecord(
PDOUtil.getDataStore(pdo),
RadarDataRetriever.populateRadarRecord(PDOUtil.getDataStore(pdo),
radarRecord);
} catch (Exception e) {
throw new DataRetrievalException(e);
@ -270,6 +268,13 @@ PDOUtil.getDataStore(pdo),
constraints.put(PRIMARY_ANGLE, angleConstraint);
}
if (request.getLocationNames() != null) {
RequestConstraint icaoConstraint = new RequestConstraint(null,
ConstraintType.IN);
icaoConstraint.setConstraintValueList(request.getLocationNames());
constraints.put(ICAO, icaoConstraint);
}
Map<String, Object> identifiers = request.getIdentifiers();
if (identifiers != null && identifiers.containsKey(ICAO)) {
constraints.put(ICAO, new RequestConstraint(identifiers.get(ICAO)
@ -332,6 +337,11 @@ PDOUtil.getDataStore(pdo),
return radarInfo;
}
@Override
public String[] getAvailableLocationNames(IGridRequest request) {
return getAvailableLocationNames(request, ICAO);
}
/**
*
* This is used to convert data from bin,radial format to radial bin format.
@ -360,7 +370,6 @@ PDOUtil.getDataStore(pdo),
this.numBins = numBins;
}
@Override
public double getDataValue(int x, int y) {
return realData.getDataValue(numBins - 1 - y, x);

View file

@ -201,6 +201,7 @@ public class SatelliteGridFactory extends AbstractGridDataPluginFactory
defaultGridData.setDataTime(pdo.getDataTime());
defaultGridData.setParameter(satelliteRecord.getPhysicalElement());
defaultGridData.setLevel(null);
defaultGridData.setLocationName(satelliteRecord.getSectorID());
// unit
Unit<?> unit = null;
if ((satelliteRecord.getUnits() == null) == false) {
@ -251,6 +252,20 @@ public class SatelliteGridFactory extends AbstractGridDataPluginFactory
constraints.put(FIELD_PYHSICAL_ELEMENT, requestConstraint);
}
if ((request.getLocationNames() == null) == false) {
RequestConstraint requestConstraint = new RequestConstraint();
requestConstraint.setConstraintType(ConstraintType.IN);
requestConstraint
.setConstraintValueList(request.getLocationNames());
constraints.put(FIELD_SECTOR_ID, requestConstraint);
}
return constraints;
}
@Override
public String[] getAvailableLocationNames(IGridRequest request) {
return getAvailableLocationNames(request, FIELD_SECTOR_ID);
}
}

View file

@ -53,8 +53,8 @@ def getData(request, times):
def getLatLonCoords(gridRequest):
return router.getLatLonCoords(gridRequest)
def getAvailableLocationNames(geometryRequest):
return router.getAvailableLocationNames(geometryRequest)
def getAvailableLocationNames(request):
return router.getAvailableLocationNames(request)
def newGeometryRequest():
return router.newGeometryRequest()

View file

@ -57,6 +57,10 @@ class IDataRequest(object):
def setLevels(self, levels):
return
@abc.abstractmethod
def setLocationNames(self, locationNames):
return
@abc.abstractmethod
def getDatatype(self):
return
@ -72,7 +76,10 @@ class IDataRequest(object):
@abc.abstractmethod
def getLevels(self):
return
@abc.abstractmethod
def getLocationNames(self):
return
class IGridRequest(IDataRequest):
__metaclass__ = abc.ABCMeta
@ -88,14 +95,6 @@ class IGeometryRequest(IDataRequest):
@abc.abstractmethod
def setEnvelope(self, env):
return
@abc.abstractmethod
def getLocationNames(self):
return
@abc.abstractmethod
def setLocationNames(self, locationNames):
return
class IData(object):
@ -112,6 +111,10 @@ class IData(object):
@abc.abstractmethod
def getLevel(self):
return
@abc.abstractmethod
def getLocationName(self, param):
return
@ -158,8 +161,4 @@ class IGeometryData(IData):
@abc.abstractmethod
def getType(self, param):
return
@abc.abstractmethod
def getLocationName(self, param):
return