Issue #189 Make Derived parameters spatially aware
Former-commit-id:317696c66f
[formerly317696c66f
[formerly f7919f7bfc3f631cc76e19710ea18feb6faf35f9]] Former-commit-id:8682b30383
Former-commit-id:2f6b9f6188
This commit is contained in:
parent
d9fb077943
commit
c866f23a03
60 changed files with 2977 additions and 2613 deletions
|
@ -49,6 +49,25 @@ import com.raytheon.uf.viz.derivparam.library.DerivedParameterGenerator;
|
|||
import com.raytheon.viz.pointdata.util.AbstractPointDataInventory;
|
||||
import com.raytheon.viz.pointdata.util.PointDataCubeAdapter;
|
||||
|
||||
/**
|
||||
*
|
||||
* Acarssounding data does not use the point data api, to get derived parameters
|
||||
* to work with acarssounding data this class will intercept point data
|
||||
* requests, and request all sounding layers from the db and reconstruct the
|
||||
* data to fit in a PointDataContainer.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Sep 26, 2012 bsteffen Initial javadoc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ACARSSoundingDataCubeAdapter extends PointDataCubeAdapter {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(ACARSSoundingDataCubeAdapter.class);
|
||||
|
@ -120,8 +139,7 @@ public class ACARSSoundingDataCubeAdapter extends PointDataCubeAdapter {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected PointDataContainer getBaseRecords(
|
||||
Collection<String> baseParameters,
|
||||
public PointDataContainer getBaseRecords(Collection<String> baseParameters,
|
||||
Map<String, RequestConstraint> queryParams) throws VizException {
|
||||
List<String> baseParams = new ArrayList<String>(baseParameters);
|
||||
String script = ScriptCreator.createScript(queryParams, 1000, "select");
|
||||
|
|
|
@ -7,26 +7,24 @@ Bundle-Activator: com.raytheon.uf.viz.derivparam.Activator
|
|||
Bundle-Vendor: RAYTHEON
|
||||
Require-Bundle: org.eclipse.core.runtime,
|
||||
javax.measure,
|
||||
com.raytheon.uf.common.dataquery,
|
||||
com.raytheon.uf.viz.core;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.datastorage;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.pointdata;bundle-version="1.12.1174"
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization
|
||||
Import-Package: com.raytheon.edex.meteoLib,
|
||||
com.raytheon.edex.util,
|
||||
com.raytheon.uf.common.comm,
|
||||
Import-Package: com.raytheon.uf.common.comm,
|
||||
com.raytheon.uf.common.dataplugin,
|
||||
com.raytheon.uf.common.dataplugin.level,
|
||||
com.raytheon.uf.common.dataplugin.persist,
|
||||
com.raytheon.uf.common.derivparam.tree,
|
||||
com.raytheon.uf.common.geospatial,
|
||||
com.raytheon.uf.common.localization,
|
||||
com.raytheon.uf.common.message.response,
|
||||
com.raytheon.uf.common.serialization,
|
||||
com.raytheon.uf.common.serialization.adapters,
|
||||
com.raytheon.uf.common.status,
|
||||
com.raytheon.uf.common.time
|
||||
com.raytheon.uf.common.time,
|
||||
com.vividsolutions.jts.geom,
|
||||
org.opengis.referencing.crs
|
||||
Export-Package: com.raytheon.uf.viz.derivparam,
|
||||
com.raytheon.uf.viz.derivparam.data,
|
||||
com.raytheon.uf.viz.derivparam.inv,
|
||||
|
|
|
@ -22,23 +22,14 @@ package com.raytheon.uf.viz.derivparam.data;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequestSet;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType;
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequestSet;
|
||||
import com.raytheon.uf.common.dataquery.responses.DbQueryResponse;
|
||||
import com.raytheon.uf.common.dataquery.responses.DbQueryResponseSet;
|
||||
import com.raytheon.uf.common.datastorage.Request;
|
||||
import com.raytheon.uf.common.datastorage.records.IDataRecord;
|
||||
import com.raytheon.uf.common.pointdata.PointDataContainer;
|
||||
|
@ -47,9 +38,10 @@ import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
|||
import com.raytheon.uf.viz.core.datastructure.IDataCubeAdapter;
|
||||
import com.raytheon.uf.viz.core.datastructure.VizDataCubeException;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode.Dependency;
|
||||
import com.raytheon.uf.viz.derivparam.inv.AvailabilityContainer;
|
||||
import com.raytheon.uf.viz.derivparam.inv.MetadataContainer;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode;
|
||||
|
||||
/**
|
||||
* Abstract data cube adapter for standard data type that uses derived
|
||||
|
@ -99,55 +91,38 @@ public abstract class AbstractDataCubeAdapter implements IDataCubeAdapter {
|
|||
@Override
|
||||
public List<List<DataTime>> timeQuery(List<TimeQueryRequest> requests)
|
||||
throws VizException {
|
||||
int mapSize = (int) (requests.size() * 1) + 1;
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache = new HashMap<AbstractRequestableLevelNode, Set<DataTime>>(
|
||||
mapSize);
|
||||
LinkedHashMap<AbstractRequestableLevelNode, TimeQueryRequest> queries = new LinkedHashMap<AbstractRequestableLevelNode, TimeQueryRequest>(
|
||||
mapSize);
|
||||
AvailabilityContainer container = createAvailabilityContainer();
|
||||
|
||||
for (TimeQueryRequest request : requests) {
|
||||
List<AbstractRequestableLevelNode> requestNodes = evaluateRequestConstraints(request
|
||||
List<AbstractRequestableNode> requestNodes = evaluateRequestConstraints(request
|
||||
.getQueryTerms());
|
||||
// pull out time queries and bulk submit
|
||||
for (AbstractRequestableLevelNode requestNode : requestNodes) {
|
||||
getTimeQuery(request, requestNode, false, queries, cache, null);
|
||||
for (AbstractRequestableNode requestNode : requestNodes) {
|
||||
container.prepareRequests(requestNode);
|
||||
}
|
||||
}
|
||||
|
||||
// set the results back into the cache's
|
||||
TimeQueryRequestSet reqSet = new TimeQueryRequestSet();
|
||||
reqSet.setRequests(queries.values().toArray(
|
||||
new TimeQueryRequest[queries.size()]));
|
||||
@SuppressWarnings("unchecked")
|
||||
List<List<DataTime>> qResponses = (List<List<DataTime>>) ThriftClient
|
||||
.sendRequest(reqSet);
|
||||
int index = 0;
|
||||
for (AbstractRequestableLevelNode node : queries.keySet()) {
|
||||
// put results into cache
|
||||
node.setTimeQueryResults(false, qResponses.get(index++), cache,
|
||||
null);
|
||||
}
|
||||
List<List<DataTime>> finalResponse = new ArrayList<List<DataTime>>(
|
||||
requests.size());
|
||||
for (TimeQueryRequest request : requests) {
|
||||
List<AbstractRequestableLevelNode> requestNodes = evaluateRequestConstraints(request
|
||||
List<AbstractRequestableNode> requestNodes = evaluateRequestConstraints(request
|
||||
.getQueryTerms());
|
||||
// pull the actual results from the cache
|
||||
Set<DataTime> results = new HashSet<DataTime>(64);
|
||||
for (AbstractRequestableLevelNode requestNode : requestNodes) {
|
||||
Set<DataTime> times = requestNode.timeQuery(request, false,
|
||||
cache, null);
|
||||
if (times == AbstractRequestableLevelNode.TIME_AGNOSTIC) {
|
||||
// TODO: include time agnostic query in main bulk query as
|
||||
// each pressure level will cause a separate query
|
||||
List<DataTime> temp = timeAgnosticQuery(request
|
||||
.getQueryTerms());
|
||||
if (temp != null) {
|
||||
results.addAll(temp);
|
||||
for (AbstractRequestableNode requestNode : requestNodes) {
|
||||
Set<TimeAndSpace> avialability = container
|
||||
.getAvailability(requestNode);
|
||||
for (TimeAndSpace ast : avialability) {
|
||||
if (ast.isTimeAgnostic()) {
|
||||
List<DataTime> temp = timeAgnosticQuery(request
|
||||
.getQueryTerms());
|
||||
if (temp != null) {
|
||||
results.addAll(temp);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
results.add(ast.getTime());
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
results.addAll(times);
|
||||
}
|
||||
}
|
||||
if (!request.isMaxQuery() || results.isEmpty()) {
|
||||
|
@ -162,35 +137,6 @@ public abstract class AbstractDataCubeAdapter implements IDataCubeAdapter {
|
|||
return finalResponse;
|
||||
}
|
||||
|
||||
protected void getTimeQuery(
|
||||
TimeQueryRequest originalRequest,
|
||||
AbstractRequestableLevelNode req,
|
||||
boolean latestOnly,
|
||||
LinkedHashMap<AbstractRequestableLevelNode, TimeQueryRequest> queries,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
throws VizException {
|
||||
List<Dependency> depends = req.getDependencies();
|
||||
if (depends.isEmpty()) {
|
||||
// is source node
|
||||
TimeQueryRequest myQ = req.getTimeQuery(originalRequest,
|
||||
latestOnly, cache, latestOnlyCache);
|
||||
if (myQ != null) {
|
||||
queries.put(req, myQ);
|
||||
}
|
||||
} else {
|
||||
for (Dependency dep : depends) {
|
||||
// TODO: Optimize dTime/fTime to use bulk query mechanism,
|
||||
// small case that is a not easy to get right with a bulk
|
||||
// query
|
||||
if (dep.timeOffset == 0 || !latestOnly) {
|
||||
getTimeQuery(originalRequest, dep.node, latestOnly,
|
||||
queries, cache, latestOnlyCache);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
@ -232,94 +178,40 @@ public abstract class AbstractDataCubeAdapter implements IDataCubeAdapter {
|
|||
@Override
|
||||
public List<Object> getData(LayerProperty property, int timeOut)
|
||||
throws VizException {
|
||||
List<AbstractRequestableLevelNode> requests = evaluateRequestConstraints(property
|
||||
List<AbstractRequestableNode> requests = evaluateRequestConstraints(property
|
||||
.getEntryQueryParameters(false));
|
||||
int mapSize = (int) (requests.size() * 1.25) + 1;
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache = new HashMap<AbstractRequestableLevelNode, List<AbstractRequestableData>>(
|
||||
mapSize);
|
||||
LinkedHashMap<AbstractRequestableLevelNode, DbQueryRequest> queries = new LinkedHashMap<AbstractRequestableLevelNode, DbQueryRequest>(
|
||||
mapSize);
|
||||
for (AbstractRequestableLevelNode req : requests) {
|
||||
getDataQuery(req, property, timeOut, queries, cache);
|
||||
}
|
||||
DbQueryRequestSet reqSet = new DbQueryRequestSet();
|
||||
reqSet.setQueries(queries.values().toArray(
|
||||
new DbQueryRequest[queries.size()]));
|
||||
DbQueryResponseSet qSetResponse = (DbQueryResponseSet) ThriftClient
|
||||
.sendRequest(reqSet);
|
||||
DbQueryResponse[] qResponses = qSetResponse.getResults();
|
||||
int index = 0;
|
||||
for (AbstractRequestableLevelNode node : queries.keySet()) {
|
||||
// put results into cache
|
||||
node.setDataQueryResults(qResponses[index++], cache);
|
||||
Set<TimeAndSpace> availability = null;
|
||||
if (property.getSelectedEntryTime() != null) {
|
||||
availability = new HashSet<TimeAndSpace>();
|
||||
for (DataTime time : property.getSelectedEntryTime()) {
|
||||
availability.add(new TimeAndSpace(time));
|
||||
}
|
||||
} else {
|
||||
availability = AvailabilityContainer.AGNOSTIC_SET;
|
||||
}
|
||||
|
||||
// pull the actual results from the cache
|
||||
List<AbstractRequestableData> requesters = new ArrayList<AbstractRequestableData>(
|
||||
requests.size());
|
||||
for (AbstractRequestableLevelNode request : requests) {
|
||||
requesters.addAll(request.getData(property, timeOut, cache));
|
||||
List<AbstractRequestableData> requesters = new ArrayList<AbstractRequestableData>();
|
||||
MetadataContainer container = createMetadataContainer(property
|
||||
.getEntryQueryParameters(false));
|
||||
for (AbstractRequestableNode request : requests) {
|
||||
container.prepareRequests(request, availability);
|
||||
}
|
||||
|
||||
for (AbstractRequestableNode request : requests) {
|
||||
requesters.addAll(container.getData(request, availability));
|
||||
}
|
||||
|
||||
return getData(property, requesters);
|
||||
}
|
||||
|
||||
protected void getDataQuery(
|
||||
AbstractRequestableLevelNode req,
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
LinkedHashMap<AbstractRequestableLevelNode, DbQueryRequest> queries,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException {
|
||||
List<Dependency> depends = req.getDependencies();
|
||||
if (depends.isEmpty()) {
|
||||
// is source node
|
||||
DbQueryRequest myQ = req.getDataQuery(property, timeOut, cache);
|
||||
if (myQ != null) {
|
||||
addDataQuery(req, myQ, queries);
|
||||
}
|
||||
} else {
|
||||
for (Dependency dep : depends) {
|
||||
// TODO: Optimize dTime/fTime to use bulk query mechanism,
|
||||
// small case that is a not easy to get right with a bulk
|
||||
// query
|
||||
if (dep.timeOffset == 0) {
|
||||
getDataQuery(dep.node, property, timeOut, queries, cache);
|
||||
}
|
||||
}
|
||||
}
|
||||
protected MetadataContainer createMetadataContainer(
|
||||
Map<String, RequestConstraint> constraints) {
|
||||
return new MetadataContainer(constraints);
|
||||
}
|
||||
|
||||
private void addDataQuery(AbstractRequestableLevelNode req,
|
||||
DbQueryRequest query,
|
||||
LinkedHashMap<AbstractRequestableLevelNode, DbQueryRequest> queries) {
|
||||
DbQueryRequest curQuery = queries.get(req);
|
||||
if (curQuery == null) {
|
||||
queries.put(req, query);
|
||||
} else {
|
||||
// merge
|
||||
// assume same DB, fields, etc, should only be different
|
||||
// time constraints since its the same node
|
||||
RequestConstraint curDTs = curQuery.getConstraints()
|
||||
.get("dataTime");
|
||||
RequestConstraint myDTs = query.getConstraints().get("dataTime");
|
||||
if (curDTs != null && myDTs != null) {
|
||||
// only merge if both require dataTimes, otherwise one
|
||||
// would be constrained when it needs everything, also
|
||||
// assuming both to be in lists and needing to be merged
|
||||
curDTs.setConstraintType(ConstraintType.IN);
|
||||
Pattern split = Pattern.compile(",");
|
||||
|
||||
String[] curVals = split.split(curDTs.getConstraintValue());
|
||||
String[] myVals = split.split(myDTs.getConstraintValue());
|
||||
HashSet<String> dups = new HashSet<String>(curVals.length
|
||||
+ myVals.length);
|
||||
dups.addAll(Arrays.asList(curVals));
|
||||
dups.addAll(Arrays.asList(myVals));
|
||||
curDTs.setConstraintValueList(dups.toArray(new String[dups
|
||||
.size()]));
|
||||
}
|
||||
}
|
||||
protected AvailabilityContainer createAvailabilityContainer() {
|
||||
return new AvailabilityContainer();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -374,7 +266,7 @@ public abstract class AbstractDataCubeAdapter implements IDataCubeAdapter {
|
|||
* @param constraints
|
||||
* @return
|
||||
*/
|
||||
protected abstract List<AbstractRequestableLevelNode> evaluateRequestConstraints(
|
||||
protected abstract List<AbstractRequestableNode> evaluateRequestConstraints(
|
||||
Map<String, RequestConstraint> constraints);
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,11 +25,17 @@ import java.util.List;
|
|||
import javax.measure.unit.Unit;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.geospatial.ISpatialObject;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
* AbstractRequestableData is the base metadata class for derived parameters. It
|
||||
* represents a single data value for a given source/parameter/level/time/space
|
||||
* combination. As well as representing the metadata it also provides a
|
||||
* getDataValue method which should return a dataValue that can be used in
|
||||
* derived parameters to calculate other parameters.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -56,7 +62,9 @@ public abstract class AbstractRequestableData {
|
|||
|
||||
protected Level level;
|
||||
|
||||
protected DataTime dataTime;
|
||||
protected DataTime dataTime = TimeAndSpace.TIME_AGNOSTIC;
|
||||
|
||||
protected ISpatialObject space = TimeAndSpace.SPACE_AGNOSTIC;
|
||||
|
||||
public AbstractRequestableData() {
|
||||
|
||||
|
@ -69,6 +77,7 @@ public abstract class AbstractRequestableData {
|
|||
this.unit = that.unit;
|
||||
this.level = that.level;
|
||||
this.dataTime = that.dataTime;
|
||||
this.space = that.space;
|
||||
}
|
||||
|
||||
// Object can be a plugin specific argument that will be passed through the
|
||||
|
@ -153,6 +162,14 @@ public abstract class AbstractRequestableData {
|
|||
this.level = level;
|
||||
}
|
||||
|
||||
public ISpatialObject getSpace() {
|
||||
return space;
|
||||
}
|
||||
|
||||
public void setSpace(ISpatialObject space) {
|
||||
this.space = space;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the dataTime
|
||||
*/
|
||||
|
@ -168,6 +185,10 @@ public abstract class AbstractRequestableData {
|
|||
this.dataTime = dataTime;
|
||||
}
|
||||
|
||||
public TimeAndSpace getTimeAndSpace() {
|
||||
return new TimeAndSpace(dataTime, space);
|
||||
}
|
||||
|
||||
public List<AbstractRequestableData> getDependencies() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
|
|
@ -31,7 +31,9 @@ import com.raytheon.uf.common.datastorage.records.IDataRecord;
|
|||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
* Represents a simple alias, where a parameter represents the same data as
|
||||
* another parameter. This does automatic unit conversion if the source data is
|
||||
* in a different unit than this object.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -53,6 +55,7 @@ public class AliasRequestableData extends AbstractRequestableData {
|
|||
public AliasRequestableData(AbstractRequestableData sourceRecord) {
|
||||
this.sourceRecord = sourceRecord;
|
||||
this.dataTime = sourceRecord.getDataTime();
|
||||
this.space = sourceRecord.space;
|
||||
}
|
||||
|
||||
public Object getDataValue(Object arg) throws VizException {
|
||||
|
|
|
@ -19,8 +19,10 @@
|
|||
**/
|
||||
package com.raytheon.uf.viz.derivparam.data;
|
||||
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
* RequestableData object for a single constant float value.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -41,6 +43,8 @@ public class FloatRequestableData extends AbstractRequestableData {
|
|||
|
||||
public FloatRequestableData(Float value) {
|
||||
this.value = value;
|
||||
this.dataTime = TimeAndSpace.TIME_AGNOSTIC;
|
||||
this.space = TimeAndSpace.SPACE_AGNOSTIC;
|
||||
}
|
||||
|
||||
public Float getDataValue() {
|
||||
|
|
|
@ -60,12 +60,11 @@ import com.raytheon.uf.viz.derivparam.library.DerivedParameterGenerator;
|
|||
import com.raytheon.uf.viz.derivparam.library.DerivedParameterGenerator.DerivParamUpdateListener;
|
||||
import com.raytheon.uf.viz.derivparam.library.IDerivParamField;
|
||||
import com.raytheon.uf.viz.derivparam.library.LevelType;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedDataNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AliasLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.CompositeAverageLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.DerivedLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.ModelRunLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.OrLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.StaticDataLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.TimeRangeLevelNode;
|
||||
|
@ -73,7 +72,10 @@ import com.raytheon.uf.viz.derivparam.tree.UnionLevelNode;
|
|||
|
||||
/**
|
||||
*
|
||||
* TODO Add Description
|
||||
* The Inventory is responsible for managing what parameters can be derived. It
|
||||
* maintains a dataTree which contains all the base parameter as well as any
|
||||
* previously used derived parameters. It can dynamically calculate what
|
||||
* parameters can be derived using the walk tree method.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -310,7 +312,7 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
request.add(result);
|
||||
}
|
||||
}
|
||||
AbstractDerivedLevelNode newNode = createDerivedNode(desc,
|
||||
AbstractDerivedDataNode newNode = createDerivedNode(desc,
|
||||
method, lNode.getLevel(), request, sNode);
|
||||
pNode.getChildNodes().put(lNode.getValue(), newNode);
|
||||
}
|
||||
|
@ -568,7 +570,7 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
* @throws InterruptedException
|
||||
* thrown if the thread was interupted during execution.
|
||||
*/
|
||||
protected synchronized List<AbstractRequestableLevelNode> walkTree(
|
||||
protected synchronized List<AbstractRequestableNode> walkTree(
|
||||
Class<? extends AbstractNode<?>> clazz,
|
||||
Collection<String> sourcesToProcess,
|
||||
Collection<String> paramsToProcess,
|
||||
|
@ -604,7 +606,7 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
}
|
||||
}
|
||||
}
|
||||
List<AbstractRequestableLevelNode> results = new ArrayList<AbstractRequestableLevelNode>();
|
||||
List<AbstractRequestableNode> results = new ArrayList<AbstractRequestableNode>();
|
||||
Set<StackEntry> nodata = new HashSet<StackEntry>(derParLibrary.size());
|
||||
Deque<StackEntry> stack = new ArrayDeque<StackEntry>();
|
||||
Iterator<String> sit = sourcesToProcess.iterator();
|
||||
|
@ -630,7 +632,7 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
Iterator<Level> lit = levelsToProcess.iterator();
|
||||
while (lit.hasNext()) {
|
||||
Level level = lit.next();
|
||||
AbstractRequestableLevelNode result = null;
|
||||
AbstractRequestableNode result = null;
|
||||
if (derive) {
|
||||
try {
|
||||
result = resolveNode(node, param, level, stack,
|
||||
|
@ -641,7 +643,7 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
}
|
||||
} else {
|
||||
ParameterNode pNode = node.getChildNode(param);
|
||||
result = (AbstractRequestableLevelNode) (pNode == null ? null
|
||||
result = (AbstractRequestableNode) (pNode == null ? null
|
||||
: pNode.getChildNode(Long.toString(level
|
||||
.getId())));
|
||||
}
|
||||
|
@ -652,10 +654,10 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
if (!includeConstant) {
|
||||
if (result.isConstant()) {
|
||||
continue;
|
||||
} else if (result instanceof AbstractDerivedLevelNode) {
|
||||
} else if (result instanceof AbstractDerivedDataNode) {
|
||||
// if we don't want constant fields I assume we
|
||||
// also don't want internal fields
|
||||
if (((AbstractDerivedLevelNode) result)
|
||||
if (((AbstractDerivedDataNode) result)
|
||||
.getDesc().isInternal()) {
|
||||
continue;
|
||||
}
|
||||
|
@ -683,10 +685,10 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
} else {
|
||||
if (sourceAliases.containsKey(source)) {
|
||||
boolean supplement = false;
|
||||
List<AbstractRequestableLevelNode> choices = new ArrayList<AbstractRequestableLevelNode>();
|
||||
List<AbstractRequestableNode> choices = new ArrayList<AbstractRequestableNode>();
|
||||
for (String aliasModel : sourceAliases
|
||||
.get(source)) {
|
||||
AbstractRequestableLevelNode alias = null;
|
||||
AbstractRequestableNode alias = null;
|
||||
if (derive) {
|
||||
try {
|
||||
alias = resolveNode(
|
||||
|
@ -700,7 +702,7 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
} else {
|
||||
ParameterNode pNode = node
|
||||
.getChildNode(param);
|
||||
alias = (AbstractRequestableLevelNode) (pNode == null ? null
|
||||
alias = (AbstractRequestableNode) (pNode == null ? null
|
||||
: pNode.getChildNode(Long
|
||||
.toString(level.getId())));
|
||||
}
|
||||
|
@ -762,7 +764,7 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
* @return
|
||||
* @throws VizCommunicationException
|
||||
*/
|
||||
protected synchronized AbstractRequestableLevelNode resolveNode(
|
||||
protected synchronized AbstractRequestableNode resolveNode(
|
||||
SourceNode sourceNode, String param, Level level,
|
||||
Deque<StackEntry> stack, Set<StackEntry> nodata)
|
||||
throws VizCommunicationException {
|
||||
|
@ -774,7 +776,7 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
&& !stack.isEmpty()) {
|
||||
stack.getFirst().autoAverage = true;
|
||||
}
|
||||
return (AbstractRequestableLevelNode) lNode;
|
||||
return (AbstractRequestableNode) lNode;
|
||||
}
|
||||
DerivParamDesc desc = derParLibrary.get(param);
|
||||
if (desc == null) {
|
||||
|
@ -799,7 +801,7 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
}
|
||||
// Any time this function returns after this point it must pop se, or
|
||||
// else!
|
||||
AbstractDerivedLevelNode autoAveragedNode = null;
|
||||
AbstractDerivedDataNode autoAveragedNode = null;
|
||||
stack.push(se);
|
||||
List<DerivParamMethod> methods = desc.getMethods();
|
||||
if (methods != null) {
|
||||
|
@ -871,7 +873,7 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
|| ((method.getFrameworkMethod() == FrameworkMethod.UNION || method
|
||||
.getFrameworkMethod() == FrameworkMethod.OR) && request
|
||||
.size() > 0)) {
|
||||
AbstractDerivedLevelNode newNode = createDerivedNode(
|
||||
AbstractDerivedDataNode newNode = createDerivedNode(
|
||||
desc, method, level, request, sourceNode);
|
||||
if (newNode != null) {
|
||||
pNode = sourceNode.getChildNode(param);
|
||||
|
@ -910,10 +912,10 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
throw new VizCommunicationException(e);
|
||||
}
|
||||
|
||||
List<AbstractRequestableLevelNode> nodes = new ArrayList<AbstractRequestableLevelNode>();
|
||||
List<AbstractRequestableNode> nodes = new ArrayList<AbstractRequestableNode>();
|
||||
int endCount = 0;
|
||||
AbstractRequestableLevelNode target = resolveNode(sourceNode,
|
||||
param, upperLevel, stack, nodata);
|
||||
AbstractRequestableNode target = resolveNode(sourceNode, param,
|
||||
upperLevel, stack, nodata);
|
||||
if (target != null) {
|
||||
endCount += 1;
|
||||
nodes.add(target);
|
||||
|
@ -1120,12 +1122,12 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
DerivParamField field, Deque<StackEntry> stack,
|
||||
Set<StackEntry> nodata) throws VizCommunicationException;
|
||||
|
||||
protected abstract AbstractDerivedLevelNode getImportNode(
|
||||
protected abstract AbstractDerivedDataNode getImportNode(
|
||||
AbstractRequestableData nodeToImport, SourceNode destSourceNode,
|
||||
DerivParamDesc desc, DerivParamMethod method, Level level);
|
||||
|
||||
protected abstract AbstractDerivedLevelNode getImportNode(
|
||||
AbstractRequestableLevelNode nodeToImport,
|
||||
protected abstract AbstractDerivedDataNode getImportNode(
|
||||
AbstractRequestableNode nodeToImport,
|
||||
String nodeToImportSourceName, SourceNode destSourceNode,
|
||||
DerivParamDesc desc, DerivParamMethod method, Level level);
|
||||
|
||||
|
@ -1142,7 +1144,7 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
* @param source
|
||||
* @return
|
||||
*/
|
||||
protected AbstractDerivedLevelNode createDerivedNode(DerivParamDesc desc,
|
||||
protected AbstractDerivedDataNode createDerivedNode(DerivParamDesc desc,
|
||||
DerivParamMethod method, Level level, List<Object> fields,
|
||||
SourceNode source) {
|
||||
switch (method.getMethodType()) {
|
||||
|
@ -1158,9 +1160,9 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
node.putStaticField(method.getFields().get(k),
|
||||
(AbstractRequestableData) obj);
|
||||
}
|
||||
if (obj instanceof AbstractRequestableLevelNode) {
|
||||
if (obj instanceof AbstractRequestableNode) {
|
||||
node.putField((DerivParamField) method.getFields().get(k),
|
||||
(AbstractRequestableLevelNode) obj);
|
||||
(AbstractRequestableNode) obj);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
|
@ -1177,10 +1179,9 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
data.setUnit(desc.getUnit());
|
||||
return new StaticDataLevelNode(level, desc, method, data,
|
||||
source.getValue());
|
||||
} else if (field instanceof AbstractRequestableLevelNode) {
|
||||
return new AliasLevelNode(
|
||||
(AbstractRequestableLevelNode) field, desc, method,
|
||||
source.getValue(), level);
|
||||
} else if (field instanceof AbstractRequestableNode) {
|
||||
return new AliasLevelNode((AbstractRequestableNode) field,
|
||||
desc, method, source.getValue(), level);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -1201,21 +1202,26 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
if (field instanceof AbstractRequestableData) {
|
||||
return getImportNode((AbstractRequestableData) field,
|
||||
source, desc, method, level);
|
||||
} else if (field instanceof AbstractRequestableLevelNode) {
|
||||
return getImportNode((AbstractRequestableLevelNode) field,
|
||||
} else if (field instanceof AbstractRequestableNode) {
|
||||
return getImportNode((AbstractRequestableNode) field,
|
||||
importSource, source, desc, method, level);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
case MODELRUN:
|
||||
return new ModelRunLevelNode(
|
||||
(AbstractRequestableLevelNode) fields.get(0), desc,
|
||||
method, source.getValue(), level);
|
||||
if (source.getDt() <= 0) {
|
||||
return null;
|
||||
}
|
||||
AbstractRequestableNode sourceLevelNode = (AbstractRequestableNode) fields
|
||||
.get(0);
|
||||
return new TimeRangeLevelNode(sourceLevelNode, desc, method,
|
||||
source.getValue(), (Integer) null, 0, source.getDt(),
|
||||
level);
|
||||
case TIMERANGE:
|
||||
if (source.getDt() <= 0) {
|
||||
return null;
|
||||
}
|
||||
AbstractRequestableLevelNode sourceNode = (AbstractRequestableLevelNode) fields
|
||||
AbstractRequestableNode sourceNode = (AbstractRequestableNode) fields
|
||||
.get(0);
|
||||
Float startTime = ((FloatRequestableData) fields.get(1))
|
||||
.getDataValue();
|
||||
|
@ -1226,18 +1232,18 @@ public abstract class AbstractInventory implements DerivParamUpdateListener {
|
|||
endTime.intValue(), source.getDt(), level);
|
||||
case SUPPLEMENT:
|
||||
case OR:
|
||||
List<AbstractRequestableLevelNode> choices = new ArrayList<AbstractRequestableLevelNode>(
|
||||
List<AbstractRequestableNode> choices = new ArrayList<AbstractRequestableNode>(
|
||||
fields.size());
|
||||
for (Object obj : fields) {
|
||||
choices.add((AbstractRequestableLevelNode) obj);
|
||||
choices.add((AbstractRequestableNode) obj);
|
||||
}
|
||||
return new OrLevelNode(level, desc, method, source.getValue(),
|
||||
choices);
|
||||
case UNION:
|
||||
List<AbstractRequestableLevelNode> nodes = new ArrayList<AbstractRequestableLevelNode>(
|
||||
List<AbstractRequestableNode> nodes = new ArrayList<AbstractRequestableNode>(
|
||||
fields.size());
|
||||
for (Object obj : fields) {
|
||||
nodes.add((AbstractRequestableLevelNode) obj);
|
||||
nodes.add((AbstractRequestableNode) obj);
|
||||
}
|
||||
return new UnionLevelNode(level, desc, method,
|
||||
source.getValue(), nodes);
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
/**
|
||||
* 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.viz.derivparam.inv;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequestSet;
|
||||
import com.raytheon.uf.common.dataquery.responses.DbQueryResponseSet;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractBaseDataNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedDataNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode.Dependency;
|
||||
|
||||
/**
|
||||
* Object for determining the vailability(in time and space) when a
|
||||
* AbstractRequestableNode can provide data. Specifically the node recursively
|
||||
* determines all dependencies and bulks requests for performance reason,
|
||||
* maintaining a cache of time to avoid any redundant requests.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 11, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class AvailabilityContainer {
|
||||
|
||||
public static final Set<TimeAndSpace> AGNOSTIC_SET = Collections
|
||||
.unmodifiableSet(new HashSet<TimeAndSpace>(Arrays
|
||||
.asList(new TimeAndSpace())));
|
||||
|
||||
protected Map<AbstractBaseDataNode, DbQueryRequest> requestCache = new HashMap<AbstractBaseDataNode, DbQueryRequest>();
|
||||
|
||||
protected Map<AbstractRequestableNode, Set<TimeAndSpace>> availabilityCache = new HashMap<AbstractRequestableNode, Set<TimeAndSpace>>();
|
||||
|
||||
/**
|
||||
* Get the availability in Time and space for a given node.
|
||||
*
|
||||
* @param node
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
public synchronized Set<TimeAndSpace> getAvailability(
|
||||
AbstractRequestableNode node) throws VizException {
|
||||
return getAvailability(node, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* recursively determine avaialbilty for a node and its dependencies,
|
||||
* doRequests should only be true for the first call, after that all
|
||||
* requests will have already been handled.
|
||||
*
|
||||
* @param node
|
||||
* @param doRequests
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
private Set<TimeAndSpace> getAvailability(AbstractRequestableNode node,
|
||||
boolean doRequests) throws VizException {
|
||||
if (availabilityCache.containsKey(node)) {
|
||||
return availabilityCache.get(node);
|
||||
}
|
||||
if (doRequests) {
|
||||
prepareRequests(node);
|
||||
processRequests();
|
||||
}
|
||||
|
||||
if (node instanceof AbstractBaseDataNode) {
|
||||
|
||||
if (availabilityCache.containsKey(node)) {
|
||||
return availabilityCache.get(node);
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"DataNode should have been handled in processRequests");
|
||||
}
|
||||
} else if (node instanceof AbstractDerivedDataNode) {
|
||||
AbstractDerivedDataNode dataNode = (AbstractDerivedDataNode) node;
|
||||
for (Dependency d : dataNode.getDependencies()) {
|
||||
getAvailability(d.node, false);
|
||||
}
|
||||
Set<TimeAndSpace> availability = dataNode
|
||||
.getAvailability(availabilityCache);
|
||||
availabilityCache.put(node, availability);
|
||||
return availability;
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"Cannot determine availability of unknown Unknown node type : "
|
||||
+ node.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This will prepare the container to request availability for the given
|
||||
* node. If this node is a derived node it will evaluate what data is needed
|
||||
* so that when getData is called it can bulk request all data. If
|
||||
* availability is needed for multiple nodes than calling this multiple
|
||||
* times before ever calling getAvailability will maximize the efficiency of
|
||||
* bulk requests.
|
||||
*
|
||||
* @param node
|
||||
* @param availability
|
||||
* @throws VizException
|
||||
*/
|
||||
public synchronized void prepareRequests(AbstractRequestableNode node) {
|
||||
if (availabilityCache.containsKey(node)
|
||||
|| requestCache.containsKey(node)) {
|
||||
return;
|
||||
}
|
||||
if (node instanceof AbstractBaseDataNode) {
|
||||
AbstractBaseDataNode dataNode = (AbstractBaseDataNode) node;
|
||||
requestCache.put(dataNode, dataNode.getAvailabilityRequest());
|
||||
} else if (node instanceof AbstractDerivedDataNode) {
|
||||
AbstractDerivedDataNode dataNode = (AbstractDerivedDataNode) node;
|
||||
for (Dependency d : dataNode.getDependencies()) {
|
||||
prepareRequests(d.node);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* process all requests, in bulk if possible.
|
||||
*
|
||||
* @throws VizException
|
||||
*/
|
||||
protected void processRequests() throws VizException {
|
||||
List<AbstractBaseDataNode> nodes = new ArrayList<AbstractBaseDataNode>();
|
||||
List<DbQueryRequest> requests = new ArrayList<DbQueryRequest>();
|
||||
for (Entry<AbstractBaseDataNode, DbQueryRequest> entry : requestCache
|
||||
.entrySet()) {
|
||||
if (availabilityCache.containsKey(entry.getKey())) {
|
||||
continue;
|
||||
} else if (entry.getValue() == null) {
|
||||
availabilityCache.put(entry.getKey(), entry.getKey()
|
||||
.getAvailability(null));
|
||||
} else {
|
||||
nodes.add(entry.getKey());
|
||||
requests.add(entry.getValue());
|
||||
}
|
||||
}
|
||||
if (nodes.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
DbQueryRequestSet requestSet = new DbQueryRequestSet();
|
||||
requestSet.setQueries(requests.toArray(new DbQueryRequest[0]));
|
||||
DbQueryResponseSet responseSet = (DbQueryResponseSet) ThriftClient
|
||||
.sendRequest(requestSet);
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
availabilityCache.put(nodes.get(i),
|
||||
nodes.get(i).getAvailability(responseSet.getResults()[i]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,223 @@
|
|||
/**
|
||||
* 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.viz.derivparam.inv;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequestSet;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.dataquery.responses.DbQueryResponseSet;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractBaseDataNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedDataNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode.Dependency;
|
||||
|
||||
/**
|
||||
* Class is responsible for pulling AbstractRequestableData out of
|
||||
* AbstractRequestableNode objects. This class manages caching and bulk
|
||||
* requesting to ensure that derived parameter requests are fully optimized.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 11, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class MetadataContainer {
|
||||
|
||||
protected final Map<String, RequestConstraint> originalConstraints;
|
||||
|
||||
protected Map<AbstractRequestableNode, Set<TimeAndSpace>> availCache = new HashMap<AbstractRequestableNode, Set<TimeAndSpace>>();
|
||||
|
||||
protected Map<AbstractRequestableNode, Set<AbstractRequestableData>> dataCache = new HashMap<AbstractRequestableNode, Set<AbstractRequestableData>>();
|
||||
|
||||
public MetadataContainer(Map<String, RequestConstraint> originalConstraints) {
|
||||
this.originalConstraints = originalConstraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* This will prepare the container to request data for the given node. If
|
||||
* this node is a derived node it will evaluate what data is needed so that
|
||||
* when getData is called it can bulk request all data. If data is needed
|
||||
* for multiple nodes than calling this multiple times before ever calling
|
||||
* getData will maximize the efficiency of bulk requests.
|
||||
*
|
||||
* @param node
|
||||
* @param availability
|
||||
* @throws VizException
|
||||
*/
|
||||
public synchronized void prepareRequests(AbstractRequestableNode node,
|
||||
Set<TimeAndSpace> availability) throws VizException {
|
||||
generateAvailability(node, availability);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the requestable data for a node with the given availability. For
|
||||
* non-derived nodes this is simple, for derived nodes this container will
|
||||
* attempt to fully optimize and cache all data requests.
|
||||
*
|
||||
* @param node
|
||||
* @param availability
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
public synchronized Set<AbstractRequestableData> getData(
|
||||
AbstractRequestableNode node, Set<TimeAndSpace> availability)
|
||||
throws VizException {
|
||||
return getData(node, availability, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* recursively called to get data, but don't reprocess availability at every
|
||||
* level, only for the first in the chain of recursive calls.
|
||||
*
|
||||
* @param node
|
||||
* @param availability
|
||||
* @param doRequests
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
private Set<AbstractRequestableData> getData(AbstractRequestableNode node,
|
||||
Set<TimeAndSpace> availability, boolean doRequests)
|
||||
throws VizException {
|
||||
if (dataCache.containsKey(node)) {
|
||||
return dataCache.get(node);
|
||||
}
|
||||
if (doRequests) {
|
||||
generateAvailability(node, availability);
|
||||
processRequests();
|
||||
}
|
||||
if (node instanceof AbstractBaseDataNode) {
|
||||
if (dataCache.containsKey(node)) {
|
||||
return dataCache.get(node);
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"DataNode should have been handled in processRequests");
|
||||
}
|
||||
} else if (node instanceof AbstractDerivedDataNode) {
|
||||
AbstractDerivedDataNode dataNode = (AbstractDerivedDataNode) node;
|
||||
for (Dependency d : dataNode.getDependencies()) {
|
||||
getData(d.node, availCache.get(d.node), false);
|
||||
}
|
||||
Set<AbstractRequestableData> data = dataNode.getData(availability,
|
||||
dataCache);
|
||||
dataCache.put(node, data);
|
||||
return data;
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"Cannot determine availability of unknown Unknown node type : "
|
||||
+ node.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Walk through all dependencies for a node and calculate the TimeAndSpace
|
||||
* where data is needed to get data for the requested TimeAndSpace.
|
||||
*
|
||||
* @param node
|
||||
* @param availability
|
||||
* @throws VizException
|
||||
*/
|
||||
private void generateAvailability(AbstractRequestableNode node,
|
||||
Set<TimeAndSpace> availability) throws VizException {
|
||||
Set<TimeAndSpace> c = availCache.get(node);
|
||||
if (c != null) {
|
||||
if (c.containsAll(availability)) {
|
||||
return;
|
||||
}
|
||||
c.addAll(availability);
|
||||
} else {
|
||||
c = new HashSet<TimeAndSpace>(availability);
|
||||
availCache.put(node, c);
|
||||
}
|
||||
if (node instanceof AbstractDerivedDataNode) {
|
||||
AbstractDerivedDataNode derivedNode = (AbstractDerivedDataNode) node;
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> avail = derivedNode
|
||||
.getDataDependency(new HashSet<TimeAndSpace>(availability));
|
||||
|
||||
for (Entry<AbstractRequestableNode, Set<TimeAndSpace>> entry : avail
|
||||
.entrySet()) {
|
||||
AbstractRequestableNode n = entry.getKey();
|
||||
Set<TimeAndSpace> a = entry.getValue();
|
||||
generateAvailability(n, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* use the availCache to determine what nodes need data and attempt to bulk
|
||||
* all requests.
|
||||
*
|
||||
* @throws VizException
|
||||
*/
|
||||
protected void processRequests() throws VizException {
|
||||
List<AbstractBaseDataNode> nodes = new ArrayList<AbstractBaseDataNode>();
|
||||
List<DbQueryRequest> requests = new ArrayList<DbQueryRequest>();
|
||||
for (AbstractRequestableNode node : availCache.keySet()) {
|
||||
if (dataCache.containsKey(node)) {
|
||||
continue;
|
||||
}
|
||||
if (node instanceof AbstractBaseDataNode) {
|
||||
AbstractBaseDataNode dataNode = (AbstractBaseDataNode) node;
|
||||
DbQueryRequest request = dataNode.getDataRequest(
|
||||
originalConstraints, availCache.get(node));
|
||||
if (request != null) {
|
||||
nodes.add(dataNode);
|
||||
requests.add(request);
|
||||
} else {
|
||||
dataCache.put(
|
||||
node,
|
||||
dataNode.getData(originalConstraints,
|
||||
availCache.get(node), null));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (requests.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
DbQueryRequestSet requestSet = new DbQueryRequestSet();
|
||||
requestSet.setQueries(requests.toArray(new DbQueryRequest[0]));
|
||||
DbQueryResponseSet responseSet = (DbQueryResponseSet) ThriftClient
|
||||
.sendRequest(requestSet);
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
AbstractBaseDataNode node = nodes.get(i);
|
||||
dataCache.put(node, node.getData(originalConstraints,
|
||||
availCache.get(node), responseSet.getResults()[i]));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,186 @@
|
|||
/**
|
||||
* 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.viz.derivparam.inv;
|
||||
|
||||
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
||||
|
||||
import com.raytheon.uf.common.geospatial.ISpatialObject;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
|
||||
/**
|
||||
* Represents a time and space(location) where data can exist. This is used in
|
||||
* derived parameters for data types to report when and where data can be
|
||||
* loaded.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 11, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class TimeAndSpace {
|
||||
|
||||
/**
|
||||
* A constant to represent the time for data that does not change over time
|
||||
* or that is available for all times, an example would be topography which
|
||||
* generally does not change on a day to day basis.
|
||||
*/
|
||||
public static final DataTime TIME_AGNOSTIC = new DataTime() {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return this == obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TIME_AGNOSTIC";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* A constant to represent the space for data that does not change over
|
||||
* space or that is available for all spaces, an example would be radar
|
||||
* elevation angle for a grid coverage, this can be calculated for any
|
||||
* gridcoverage.
|
||||
*/
|
||||
public static final ISpatialObject SPACE_AGNOSTIC = new ISpatialObject() {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Integer getNy() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getNx() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Geometry getGeometry() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CoordinateReferenceSystem getCrs() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SPACE_AGNOSTIC";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private final DataTime time;
|
||||
|
||||
private final ISpatialObject space;
|
||||
|
||||
public TimeAndSpace() {
|
||||
this(TIME_AGNOSTIC, SPACE_AGNOSTIC);
|
||||
}
|
||||
|
||||
public TimeAndSpace(DataTime time) {
|
||||
this(time, SPACE_AGNOSTIC);
|
||||
|
||||
}
|
||||
|
||||
public TimeAndSpace(ISpatialObject space) {
|
||||
this(TIME_AGNOSTIC, space);
|
||||
}
|
||||
|
||||
public TimeAndSpace(DataTime time, ISpatialObject space) {
|
||||
this.time = time;
|
||||
this.space = space;
|
||||
}
|
||||
|
||||
public DataTime getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public ISpatialObject getSpace() {
|
||||
return space;
|
||||
}
|
||||
|
||||
public boolean isTimeAgnostic() {
|
||||
return this.time == TIME_AGNOSTIC;
|
||||
}
|
||||
|
||||
public boolean isSpaceAgnostic() {
|
||||
return space == SPACE_AGNOSTIC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((space == null) ? 0 : space.hashCode());
|
||||
result = prime * result + ((time == null) ? 0 : time.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
TimeAndSpace other = (TimeAndSpace) obj;
|
||||
if (space == null) {
|
||||
if (other.space != null)
|
||||
return false;
|
||||
} else if (!space.equals(other.space))
|
||||
return false;
|
||||
if (time == null) {
|
||||
if (other.time != null)
|
||||
return false;
|
||||
} else if (!time.equals(other.time))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("AvailSpT: Time: ");
|
||||
sb.append(time);
|
||||
sb.append(", Space: ");
|
||||
sb.append(space);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,348 @@
|
|||
/**
|
||||
* 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.viz.derivparam.inv;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.geospatial.ISpatialObject;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
|
||||
/**
|
||||
* The primary function of this class is two find the intersection between two
|
||||
* collections of TimeAndSpace objects. This will compare all the TimeAndSpace
|
||||
* objects in each collection and find "matches". The simplest matches are when
|
||||
* both time and space objects are equal. More complex matches can be created
|
||||
* when times are equal but one is time agnostic or spaces are equal and one is
|
||||
* space agnostic. Finally if for one of the Collections contains a time and
|
||||
* space agnostic TimeAndSpace than it will match everything.
|
||||
*
|
||||
* Time matching is a little more complex than space because you can configure
|
||||
* ignoreRange and validMatch so that times can be considered matching even if
|
||||
* they aren't identical, as long as they are referencing a similar time, for
|
||||
* more information see the setters for those flags.
|
||||
*
|
||||
* When determining matches this will choose the most specific match. For
|
||||
* example if a TimeAndSpace object can match an object that matches space but
|
||||
* only matches validTime or it can match an object that matches space but is
|
||||
* time agnostic, then it will choose the valid time match since that is more
|
||||
* specific than the agnostic. This order is defined by the natural order of the
|
||||
* MatchType enum.
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* May 8, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class TimeAndSpaceMatcher {
|
||||
|
||||
private boolean ignoreRange = false;
|
||||
|
||||
private boolean matchValid = false;
|
||||
|
||||
/**
|
||||
* When ignore range is true then times with different ranges are considered
|
||||
* matching if they are the same in all other ways, when false times are
|
||||
* considered nonmatching if the range is not identical.
|
||||
*
|
||||
* @param ignoreRange
|
||||
*/
|
||||
public void setIgnoreRange(boolean ignoreRange) {
|
||||
this.ignoreRange = ignoreRange;
|
||||
}
|
||||
|
||||
/**
|
||||
* When match valid is true then dataTimes are compared based off valid
|
||||
* time, when it is false the refTime and forecast time are considered
|
||||
* sperately and both must match to create a match. Even when matchValid is
|
||||
* true, if there is a time where forecast and refTime amtch it will be
|
||||
* prefered to a time where only validTime matches
|
||||
*
|
||||
* @param matchValid
|
||||
*/
|
||||
public void setMatchValid(boolean matchValid) {
|
||||
this.matchValid = matchValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the match operation. The result is returned as a map, where the
|
||||
* key is the intersected TimeAndSpace and the values are a MatchResult that
|
||||
* contains the SpaceAndTime needed from each collection to represent that
|
||||
* time.
|
||||
*
|
||||
* @param times1
|
||||
* @param times2
|
||||
* @return
|
||||
*/
|
||||
public Map<TimeAndSpace, MatchResult> match(
|
||||
Collection<TimeAndSpace> times1, Collection<TimeAndSpace> times2) {
|
||||
Map<TimeAndSpace, MatchResult> result = new HashMap<TimeAndSpace, MatchResult>();
|
||||
for (TimeAndSpace t1 : times1) {
|
||||
for (TimeAndSpace t2 : times2) {
|
||||
MatchResult res = createMatchResult(t1, t2);
|
||||
if (res != null) {
|
||||
MatchResult prev = result.get(res.getMerge());
|
||||
if (prev == null
|
||||
|| prev.getMatchValue().compareTo(
|
||||
res.getMatchValue()) > 0) {
|
||||
result.put(res.getMerge(), res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given two TimeAndSpace objects attempts to determine what they have in
|
||||
* common, if anything and return a MatchResult or null if there is no
|
||||
* match.
|
||||
*
|
||||
* @param t1
|
||||
* @param t2
|
||||
* @return
|
||||
*/
|
||||
private MatchResult createMatchResult(TimeAndSpace t1, TimeAndSpace t2) {
|
||||
MatchType matchValue;
|
||||
DataTime time = null;
|
||||
ISpatialObject space = null;
|
||||
// first determine what space a match between these two times would have
|
||||
boolean spaceAgn = false;
|
||||
if (t1.getSpace().equals(t2.getSpace())) {
|
||||
// If they match that is best
|
||||
space = t1.getSpace();
|
||||
} else if (t1.isSpaceAgnostic()) {
|
||||
// space agnostic will match something with space.
|
||||
spaceAgn = true;
|
||||
space = t2.getSpace();
|
||||
} else if (t2.isSpaceAgnostic()) {
|
||||
// again one is agnostic
|
||||
spaceAgn = true;
|
||||
space = t1.getSpace();
|
||||
} else {
|
||||
// no spatial match, means no match at all.
|
||||
return null;
|
||||
}
|
||||
|
||||
// Next determine how well the times match
|
||||
if (t1.isTimeAgnostic()) {
|
||||
// When one is agnostic it will match anything.
|
||||
time = t2.getTime();
|
||||
matchValue = spaceAgn ? MatchType.AGNOSTIC_MATCH
|
||||
: MatchType.SPACE_MATCH;
|
||||
} else if (t2.isTimeAgnostic()) {
|
||||
// again one is agnostic
|
||||
time = t1.getTime();
|
||||
matchValue = spaceAgn ? MatchType.AGNOSTIC_MATCH
|
||||
: MatchType.SPACE_MATCH;
|
||||
} else if (t1.getTime().equals(t2.getTime())) {
|
||||
// A perfect time match is always best.
|
||||
time = t1.getTime();
|
||||
matchValue = spaceAgn ? MatchType.TIME_MATCH : MatchType.BOTH_MATCH;
|
||||
} else if (ignoreRange
|
||||
&& t1.getTime().getMatchRef() == t2.getTime().getMatchRef()
|
||||
&& t1.getTime().getMatchFcst() == t2.getTime().getMatchFcst()) {
|
||||
// If the ignoreRanfe flag is set then it is still considered a
|
||||
// match even if the ranges are different.
|
||||
time = new DataTime(t1.getTime().getRefTime(), t1.getTime()
|
||||
.getFcstTime());
|
||||
matchValue = spaceAgn ? MatchType.TIME_IGNORE_RANGE
|
||||
: MatchType.BOTH_IGNORE_RANGE;
|
||||
} else if (matchValid
|
||||
&& t1.getTime().getMatchValid() == t2.getTime().getMatchValid()) {
|
||||
// finally last valid allows us to mix different
|
||||
// refTime/forecastTimes as long as valid matches.
|
||||
if (t1.getTime().getMatchRef() > t2.getTime().getMatchRef()) {
|
||||
time = new DataTime(t1.getTime().getRefTime(), t1.getTime()
|
||||
.getFcstTime());
|
||||
} else {
|
||||
time = new DataTime(t2.getTime().getRefTime(), t2.getTime()
|
||||
.getFcstTime());
|
||||
}
|
||||
matchValue = spaceAgn ? MatchType.TIME_VALID : MatchType.BOTH_VALID;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return new MatchResult(t1, t2, new TimeAndSpace(time, space),
|
||||
matchValue);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Class to contain the result of a match operation for 2 matching
|
||||
* TimeAndSpace objects
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Sep 27, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public static class MatchResult {
|
||||
|
||||
/**
|
||||
* The TimeAndSpace from the first collection that matches
|
||||
*/
|
||||
private final TimeAndSpace t1;
|
||||
|
||||
/**
|
||||
* The TimeAndSpace from the second collection that matches
|
||||
*/
|
||||
private final TimeAndSpace t2;
|
||||
|
||||
/**
|
||||
* The TimeAndSpace from the first collection that matches
|
||||
*/
|
||||
private final TimeAndSpace merge;
|
||||
|
||||
/**
|
||||
* How good of a match is this.
|
||||
*/
|
||||
private final MatchType matchValue;
|
||||
|
||||
public MatchResult(TimeAndSpace t1, TimeAndSpace t2,
|
||||
TimeAndSpace merge, MatchType matchValue) {
|
||||
this.t1 = t1;
|
||||
this.t2 = t2;
|
||||
this.merge = merge;
|
||||
this.matchValue = matchValue;
|
||||
}
|
||||
|
||||
public TimeAndSpace get1() {
|
||||
return t1;
|
||||
}
|
||||
|
||||
public TimeAndSpace get2() {
|
||||
return t2;
|
||||
}
|
||||
|
||||
public TimeAndSpace getMerge() {
|
||||
return merge;
|
||||
}
|
||||
|
||||
public MatchType getMatchValue() {
|
||||
return matchValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* An enum which represents the quality of the match, The best matches are
|
||||
* when both Time and Space objects are matches, but there are other
|
||||
* matches, usually involving either Time or Space agnostic that are not as
|
||||
* ideal but are suitable.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Sep 27, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public static enum MatchType {
|
||||
|
||||
// Time and space match perfectly
|
||||
BOTH_MATCH,
|
||||
|
||||
// Space matches perfectly but time only matches if you ignore range
|
||||
BOTH_IGNORE_RANGE,
|
||||
|
||||
// Space matches perfectly but time only matches valid time
|
||||
BOTH_VALID,
|
||||
|
||||
// one is space agnostic and time matches
|
||||
TIME_MATCH,
|
||||
|
||||
// one is space agnostic but time only matches if you ignore range
|
||||
TIME_IGNORE_RANGE,
|
||||
|
||||
// one is space agnostic but time only matches valid time
|
||||
TIME_VALID,
|
||||
|
||||
// space matches perfectly and one is time agnostic
|
||||
SPACE_MATCH,
|
||||
|
||||
// one is both time and space agnostic so they match even though
|
||||
// they have nothing in common
|
||||
AGNOSTIC_MATCH;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the result of a match this will pull out the unique SpaceAndTime
|
||||
* objects that matched from the second Collection passed to match.
|
||||
*
|
||||
* @param matchResults
|
||||
* @return
|
||||
*/
|
||||
public static Set<TimeAndSpace> getAll2(
|
||||
Map<TimeAndSpace, MatchResult> matchResults) {
|
||||
Set<TimeAndSpace> result = new HashSet<TimeAndSpace>(
|
||||
matchResults.size());
|
||||
for (MatchResult mr : matchResults.values()) {
|
||||
result.add(mr.get2());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the result of a match this will pull out the unique SpaceAndTime
|
||||
* objects that matched from the first Collection passed to match.
|
||||
*
|
||||
* @param matchResults
|
||||
* @return
|
||||
*/
|
||||
public static Set<TimeAndSpace> getAll1(
|
||||
Map<TimeAndSpace, MatchResult> matchResults) {
|
||||
Set<TimeAndSpace> result = new HashSet<TimeAndSpace>(
|
||||
matchResults.size());
|
||||
for (MatchResult mr : matchResults.values()) {
|
||||
result.add(mr.get1());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -20,15 +20,14 @@
|
|||
package com.raytheon.uf.viz.derivparam.tree;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequest;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
|
||||
|
@ -50,16 +49,16 @@ import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
|||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public abstract class AbstractAliasLevelNode extends AbstractDerivedLevelNode {
|
||||
public abstract class AbstractAliasLevelNode extends AbstractDerivedDataNode {
|
||||
|
||||
protected AbstractRequestableLevelNode sourceNode;
|
||||
protected AbstractRequestableNode sourceNode;
|
||||
|
||||
public AbstractAliasLevelNode(AbstractAliasLevelNode that) {
|
||||
super(that);
|
||||
this.sourceNode = that.sourceNode;
|
||||
}
|
||||
|
||||
public AbstractAliasLevelNode(AbstractRequestableLevelNode sourceNode,
|
||||
public AbstractAliasLevelNode(AbstractRequestableNode sourceNode,
|
||||
DerivParamDesc desc, DerivParamMethod method, String modelName,
|
||||
Level level) {
|
||||
super(sourceNode, desc, method, modelName);
|
||||
|
@ -67,32 +66,6 @@ public abstract class AbstractAliasLevelNode extends AbstractDerivedLevelNode {
|
|||
setLevel(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<DataTime> timeQueryInternal(TimeQueryRequest originalRequest,
|
||||
boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
throws VizException {
|
||||
return sourceNode.timeQuery(originalRequest, latestOnly, cache,
|
||||
latestOnlyCache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTimeAgnostic() {
|
||||
return sourceNode.isTimeAgnostic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, RequestConstraint> getRequestConstraintMap() {
|
||||
// TODO Auto-generated method stub
|
||||
return sourceNode.getRequestConstraintMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRequestConstraints() {
|
||||
return sourceNode.hasRequestConstraints();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Dependency> getDependencies() {
|
||||
return Arrays.asList(new Dependency(sourceNode, 0));
|
||||
|
@ -134,4 +107,19 @@ public abstract class AbstractAliasLevelNode extends AbstractDerivedLevelNode {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TimeAndSpace> getAvailability(
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> availability)
|
||||
throws VizException {
|
||||
return availability.get(sourceNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<AbstractRequestableNode, Set<TimeAndSpace>> getDataDependency(
|
||||
Set<TimeAndSpace> times) {
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> result = new HashMap<AbstractRequestableNode, Set<TimeAndSpace>>();
|
||||
result.put(sourceNode, times);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
/**
|
||||
* 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.viz.derivparam.tree;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.derivparam.tree.LevelNode;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* May 10, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public abstract class AbstractBaseDataNode extends AbstractRequestableNode {
|
||||
|
||||
public AbstractBaseDataNode() {
|
||||
super();
|
||||
}
|
||||
|
||||
public AbstractBaseDataNode(Level level) {
|
||||
super(level);
|
||||
}
|
||||
|
||||
public AbstractBaseDataNode(LevelNode that) {
|
||||
super(that);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional method to provide a request to the AvailabilityContainer so that
|
||||
* it can bulk all requests to edex to save time. The result of the request
|
||||
* will be passed to getAvailability. If the return value is null then the
|
||||
* response passed to getAvailability will be null also.
|
||||
*
|
||||
* @param originalConstraints
|
||||
* the original constraints passed to the data cube container
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract DbQueryRequest getAvailabilityRequest();
|
||||
|
||||
/**
|
||||
* Optional method to provide a request to the DataContainer so that it can
|
||||
* bulk all requests to edex to save time. The result of the request will be
|
||||
* passed to getData. If the return value is null then the response passed
|
||||
* to getData will be null also.
|
||||
*
|
||||
*
|
||||
* @param originalConstraints
|
||||
* the original constraints passed to the data cube container
|
||||
* @param availability
|
||||
* the TimeAndSpace objects where data is being requested
|
||||
* @return
|
||||
*/
|
||||
public abstract DbQueryRequest getDataRequest(
|
||||
Map<String, RequestConstraint> originalConstraints,
|
||||
Set<TimeAndSpace> availability);
|
||||
|
||||
/**
|
||||
* Determine where and when data is available for this node.
|
||||
*
|
||||
* @param originalConstraints
|
||||
* the original constraints passed to the data cube container
|
||||
* @param response
|
||||
* if getAvailabilityRequest() returned a request then this will
|
||||
* have the response to that request.
|
||||
* @return the TimeAndSpace when this node has available data.
|
||||
* @throws VizException
|
||||
*/
|
||||
public abstract Set<TimeAndSpace> getAvailability(Object response)
|
||||
throws VizException;
|
||||
|
||||
/**
|
||||
* Get data from this node.
|
||||
*
|
||||
* @param originalConstraints
|
||||
* the original constraints passed to the data cube container
|
||||
* @param availability
|
||||
* the TimeAndSpace objects where data is being requested
|
||||
* @param response
|
||||
* response to the server request returned by getDataRequest.
|
||||
* @return
|
||||
*/
|
||||
public abstract Set<AbstractRequestableData> getData(
|
||||
Map<String, RequestConstraint> orignalConstraints,
|
||||
Set<TimeAndSpace> availability, Object response)
|
||||
throws VizException;
|
||||
|
||||
@Override
|
||||
public boolean isConstant() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -20,26 +20,20 @@
|
|||
package com.raytheon.uf.viz.derivparam.tree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequest;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.catalog.CatalogQuery;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.catalog.ScriptCreator;
|
||||
import com.raytheon.uf.viz.core.comm.Loader;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.data.CubeRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpaceMatcher;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpaceMatcher.MatchResult;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
|
||||
|
@ -66,9 +60,9 @@ import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
|||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public abstract class AbstractCubeLevelNode extends AbstractDerivedLevelNode {
|
||||
public abstract class AbstractCubeLevelNode extends AbstractDerivedDataNode {
|
||||
|
||||
protected List<CubeLevel<AbstractRequestableLevelNode, AbstractRequestableLevelNode>> levels;
|
||||
protected List<CubeLevel<AbstractRequestableNode, AbstractRequestableNode>> levels;
|
||||
|
||||
public AbstractCubeLevelNode(AbstractCubeLevelNode that) {
|
||||
super(that);
|
||||
|
@ -77,7 +71,7 @@ public abstract class AbstractCubeLevelNode extends AbstractDerivedLevelNode {
|
|||
}
|
||||
|
||||
public AbstractCubeLevelNode(
|
||||
List<CubeLevel<AbstractRequestableLevelNode, AbstractRequestableLevelNode>> levels,
|
||||
List<CubeLevel<AbstractRequestableNode, AbstractRequestableNode>> levels,
|
||||
String modelName) {
|
||||
this.levels = levels;
|
||||
this.modelName = modelName;
|
||||
|
@ -87,7 +81,7 @@ public abstract class AbstractCubeLevelNode extends AbstractDerivedLevelNode {
|
|||
public AbstractCubeLevelNode(
|
||||
Level level,
|
||||
String modelName,
|
||||
List<CubeLevel<AbstractRequestableLevelNode, AbstractRequestableLevelNode>> levels) {
|
||||
List<CubeLevel<AbstractRequestableNode, AbstractRequestableNode>> levels) {
|
||||
this.setLevel(level);
|
||||
this.levels = levels;
|
||||
this.modelName = modelName;
|
||||
|
@ -99,7 +93,7 @@ public abstract class AbstractCubeLevelNode extends AbstractDerivedLevelNode {
|
|||
DerivParamDesc desc,
|
||||
DerivParamMethod method,
|
||||
String modelName,
|
||||
List<CubeLevel<AbstractRequestableLevelNode, AbstractRequestableLevelNode>> levels) {
|
||||
List<CubeLevel<AbstractRequestableNode, AbstractRequestableNode>> levels) {
|
||||
super(level, desc, method, modelName);
|
||||
this.levels = levels;
|
||||
this.setValue("3D");
|
||||
|
@ -111,90 +105,68 @@ public abstract class AbstractCubeLevelNode extends AbstractDerivedLevelNode {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<AbstractRequestableData> getDataInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
public Map<AbstractRequestableNode, Set<TimeAndSpace>> getDataDependency(
|
||||
Set<TimeAndSpace> availability) throws VizException {
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> result = new HashMap<AbstractRequestableNode, Set<TimeAndSpace>>();
|
||||
for (CubeLevel<AbstractRequestableNode, AbstractRequestableNode> level : levels) {
|
||||
result.put(level.getParam(), availability);
|
||||
result.put(level.getPressure(), availability);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AbstractRequestableData> getData(
|
||||
Set<TimeAndSpace> availability,
|
||||
Map<AbstractRequestableNode, Set<AbstractRequestableData>> dependencyData)
|
||||
throws VizException {
|
||||
List<AbstractRequestableLevelNode> requests = new ArrayList<AbstractRequestableLevelNode>(
|
||||
levels.size());
|
||||
List<AbstractRequestableLevelNode> timeAgnosticRequests = new ArrayList<AbstractRequestableLevelNode>();
|
||||
List<AbstractRequestableData> rawRecords = new ArrayList<AbstractRequestableData>(
|
||||
levels.size());
|
||||
List<AbstractRequestableData> timeAgnosticRecords = new ArrayList<AbstractRequestableData>();
|
||||
|
||||
for (CubeLevel<AbstractRequestableLevelNode, AbstractRequestableLevelNode> level : levels) {
|
||||
AbstractRequestableLevelNode node = level.getParam();
|
||||
if (cache.containsKey(node)) {
|
||||
List<AbstractRequestableData> cachedRecords = cache.get(node);
|
||||
if (node.isTimeAgnostic()) {
|
||||
timeAgnosticRecords.addAll(cachedRecords);
|
||||
} else {
|
||||
boolean foundMissingTime = false;
|
||||
Set<DataTime> selectedTimes = new HashSet<DataTime>(
|
||||
Arrays.asList(property.getSelectedEntryTime()));
|
||||
for (AbstractRequestableData cRec : cachedRecords) {
|
||||
if (!selectedTimes.contains(cRec.getDataTime())) {
|
||||
foundMissingTime = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundMissingTime) {
|
||||
requests.add(node);
|
||||
} else {
|
||||
rawRecords.addAll(cachedRecords);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (node.isTimeAgnostic()) {
|
||||
timeAgnosticRequests.add(node);
|
||||
} else {
|
||||
requests.add(node);
|
||||
Map<TimeAndSpace, List<AbstractRequestableData>> paramMap = new HashMap<TimeAndSpace, List<AbstractRequestableData>>();
|
||||
Map<TimeAndSpace, List<AbstractRequestableData>> presMap = new HashMap<TimeAndSpace, List<AbstractRequestableData>>();
|
||||
for (CubeLevel<AbstractRequestableNode, AbstractRequestableNode> level : levels) {
|
||||
Set<AbstractRequestableData> paramRecs = dependencyData.get(level
|
||||
.getParam());
|
||||
for (AbstractRequestableData paramRec : paramRecs) {
|
||||
TimeAndSpace ast = paramRec.getTimeAndSpace();
|
||||
List<AbstractRequestableData> paramList = paramMap.get(ast);
|
||||
if (paramList == null) {
|
||||
paramList = new ArrayList<AbstractRequestableData>();
|
||||
paramMap.put(ast, paramList);
|
||||
}
|
||||
paramList.add(paramRec);
|
||||
}
|
||||
}
|
||||
|
||||
retrieveRecords(requests, property, timeOut, cache, rawRecords);
|
||||
retrieveRecords(timeAgnosticRequests, property, timeOut, cache,
|
||||
timeAgnosticRecords);
|
||||
Map<DataTime, CubeRequestableData> bins = new HashMap<DataTime, CubeRequestableData>(
|
||||
(int) (property.getSelectedEntryTime().length * 1.3));
|
||||
processRecords(rawRecords, property, true, false, bins);
|
||||
processRecords(timeAgnosticRecords, property, true, true, bins);
|
||||
requests.clear();
|
||||
timeAgnosticRequests.clear();
|
||||
rawRecords.clear();
|
||||
timeAgnosticRecords.clear();
|
||||
for (CubeLevel<AbstractRequestableLevelNode, AbstractRequestableLevelNode> level : levels) {
|
||||
AbstractRequestableLevelNode node = level.getPressure();
|
||||
if (cache.containsKey(node)) {
|
||||
List<AbstractRequestableData> cachedRecords = cache.get(node);
|
||||
if (node.isTimeAgnostic()) {
|
||||
timeAgnosticRecords.addAll(cachedRecords);
|
||||
} else {
|
||||
rawRecords.addAll(cachedRecords);
|
||||
}
|
||||
} else {
|
||||
if (node.isTimeAgnostic()) {
|
||||
timeAgnosticRequests.add(node);
|
||||
} else {
|
||||
requests.add(node);
|
||||
Set<AbstractRequestableData> presRecs = dependencyData.get(level
|
||||
.getPressure());
|
||||
for (AbstractRequestableData presRec : presRecs) {
|
||||
TimeAndSpace ast = presRec.getTimeAndSpace();
|
||||
List<AbstractRequestableData> presList = presMap.get(ast);
|
||||
if (presList == null) {
|
||||
presList = new ArrayList<AbstractRequestableData>();
|
||||
presMap.put(ast, presList);
|
||||
}
|
||||
presList.add(presRec);
|
||||
}
|
||||
}
|
||||
retrieveRecords(requests, property, timeOut, cache, rawRecords);
|
||||
retrieveRecords(timeAgnosticRequests, property, timeOut, cache,
|
||||
timeAgnosticRecords);
|
||||
processRecords(rawRecords, property, false, false, bins);
|
||||
processRecords(timeAgnosticRecords, property, false, true, bins);
|
||||
|
||||
List<AbstractRequestableData> records = new ArrayList<AbstractRequestableData>(
|
||||
bins.size());
|
||||
for (Entry<DataTime, CubeRequestableData> entry : bins.entrySet()) {
|
||||
CubeRequestableData record = entry.getValue();
|
||||
}
|
||||
Map<TimeAndSpace, MatchResult> matches = new TimeAndSpaceMatcher()
|
||||
.match(paramMap.keySet(), presMap.keySet());
|
||||
Set<AbstractRequestableData> records = new HashSet<AbstractRequestableData>();
|
||||
for (Entry<TimeAndSpace, MatchResult> match : matches.entrySet()) {
|
||||
List<AbstractRequestableData> paramList = paramMap.get(match
|
||||
.getValue().get1());
|
||||
CubeRequestableData record = new CubeRequestableData(
|
||||
paramList.get(0));
|
||||
for (AbstractRequestableData paramRec : paramList) {
|
||||
record.addParam(paramRec);
|
||||
}
|
||||
List<AbstractRequestableData> presList = presMap.get(match
|
||||
.getValue().get2());
|
||||
for (AbstractRequestableData presRec : presList) {
|
||||
record.addPressure(presRec);
|
||||
}
|
||||
record.validate();
|
||||
if (record.size() >= 2) {
|
||||
record.setDataTime(entry.getKey());
|
||||
record.setDataTime(match.getKey().getTime());
|
||||
record.setSpace(match.getKey().getSpace());
|
||||
modifyRequest(record);
|
||||
records.add(record);
|
||||
}
|
||||
|
@ -202,183 +174,25 @@ public abstract class AbstractCubeLevelNode extends AbstractDerivedLevelNode {
|
|||
return records;
|
||||
}
|
||||
|
||||
private void retrieveRecords(
|
||||
List<AbstractRequestableLevelNode> requests,
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache,
|
||||
List<AbstractRequestableData> retrievedRecords) throws VizException {
|
||||
retrievedRecords.addAll(mergedGetData(merge(requests), property,
|
||||
timeOut));
|
||||
for (AbstractRequestableLevelNode request : requests) {
|
||||
retrievedRecords.addAll(request.getData(property, timeOut, cache));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Set<TimeAndSpace> getAvailability(
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> availability)
|
||||
throws VizException {
|
||||
// things in one are available for one level
|
||||
Set<TimeAndSpace> one = new HashSet<TimeAndSpace>();
|
||||
// things in two are available for two levels.
|
||||
Set<TimeAndSpace> two = new HashSet<TimeAndSpace>();
|
||||
|
||||
private void processRecords(List<AbstractRequestableData> records,
|
||||
LayerProperty property, boolean isParam, boolean isTimeAgnostic,
|
||||
Map<DataTime, CubeRequestableData> bins) {
|
||||
DataTime[] keys = new DataTime[1];
|
||||
if (isTimeAgnostic) {
|
||||
keys = property.getSelectedEntryTime();
|
||||
}
|
||||
|
||||
for (AbstractRequestableData record : records) {
|
||||
if (!isTimeAgnostic) {
|
||||
keys[0] = record.getDataTime();
|
||||
}
|
||||
|
||||
for (DataTime dt : keys) {
|
||||
if (dt != null) {
|
||||
CubeRequestableData bin = bins.get(dt);
|
||||
if (bin == null) {
|
||||
bin = new CubeRequestableData(record);
|
||||
bins.put(dt, bin);
|
||||
}
|
||||
if (isParam) {
|
||||
bin.addParam(record);
|
||||
} else {
|
||||
bin.addPressure(record);
|
||||
}
|
||||
for (CubeLevel<AbstractRequestableNode, AbstractRequestableNode> level : levels) {
|
||||
for (TimeAndSpace time : availability.get(level.getParam())) {
|
||||
if (one.contains(time)) {
|
||||
two.add(time);
|
||||
} else {
|
||||
one.add(time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTimeAgnostic() {
|
||||
boolean timeAgnostic = true;
|
||||
|
||||
for (CubeLevel<AbstractRequestableLevelNode, AbstractRequestableLevelNode> level : levels) {
|
||||
if (!level.getPressure().isTimeAgnostic()
|
||||
|| !level.getParam().isTimeAgnostic()) {
|
||||
timeAgnostic = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return timeAgnostic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform any filtering on the requestContraintsToFilter based on the
|
||||
* baseRequestConstraints.
|
||||
*
|
||||
* @param baseRequestConstraints
|
||||
* @param requestContraintsToFilter
|
||||
*/
|
||||
protected abstract void filter(
|
||||
Map<String, RequestConstraint> baseRequestConstraints,
|
||||
Map<String, RequestConstraint> requestContraintsToFilter);
|
||||
|
||||
@Override
|
||||
public Set<DataTime> timeQueryInternal(TimeQueryRequest originalRequest,
|
||||
boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
throws VizException {
|
||||
Set<DataTime> results = new HashSet<DataTime>();
|
||||
List<AbstractRequestableLevelNode> requests = new ArrayList<AbstractRequestableLevelNode>(
|
||||
levels.size() * 2);
|
||||
|
||||
for (CubeLevel<AbstractRequestableLevelNode, AbstractRequestableLevelNode> level : levels) {
|
||||
AbstractRequestableLevelNode node = level.getPressure();
|
||||
if (cache.containsKey(node)) {
|
||||
results.addAll(cache.get(node));
|
||||
} else if (!node.isTimeAgnostic()) {
|
||||
requests.add(node);
|
||||
}
|
||||
node = level.getParam();
|
||||
if (cache.containsKey(node)) {
|
||||
results.addAll(cache.get(node));
|
||||
} else if (!node.isTimeAgnostic()) {
|
||||
requests.add(node);
|
||||
}
|
||||
}
|
||||
|
||||
if (requests.size() == 0 && results.size() == 0) {
|
||||
return TIME_AGNOSTIC;
|
||||
}
|
||||
|
||||
results.addAll(mergedTimeQuery(merge(requests), latestOnly));
|
||||
for (AbstractRequestableLevelNode request : requests) {
|
||||
results.addAll(request.timeQuery(originalRequest, latestOnly,
|
||||
cache, latestOnlyCache));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* A merged time query performs a single time query from multiple requests
|
||||
* when possible and removes those requests from the list.
|
||||
*
|
||||
* @param requests
|
||||
* @param latestOnly
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
protected Set<DataTime> mergedTimeQuery(
|
||||
List<Map<String, RequestConstraint>> requests, boolean latestOnly)
|
||||
throws VizException {
|
||||
Set<DataTime> results = new HashSet<DataTime>();
|
||||
for (Map<String, RequestConstraint> mergeMap : requests) {
|
||||
DataTime[] resultsArr = CatalogQuery.performTimeQuery(mergeMap,
|
||||
latestOnly, null);
|
||||
|
||||
if (resultsArr != null) {
|
||||
for (int i = 0; i < resultsArr.length; i++) {
|
||||
results.add(resultsArr[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
protected List<AbstractRequestableData> mergedGetData(
|
||||
List<Map<String, RequestConstraint>> requests,
|
||||
LayerProperty property, int timeOut) throws VizException {
|
||||
List<Object> results = new ArrayList<Object>();
|
||||
Map<String, RequestConstraint> oldQuery = property
|
||||
.getEntryQueryParameters(false);
|
||||
int numberOfImages = property.getNumberOfImages();
|
||||
if (numberOfImages < 9999) {
|
||||
property.setNumberOfImages(9999);
|
||||
}
|
||||
try {
|
||||
for (Map<String, RequestConstraint> mergeMap : requests) {
|
||||
Map<String, RequestConstraint> newQuery = new HashMap<String, RequestConstraint>(
|
||||
mergeMap);
|
||||
filter(oldQuery, newQuery);
|
||||
property.setEntryQueryParameters(newQuery, false);
|
||||
// TODO: replace
|
||||
String scriptToExecute = ScriptCreator.createScript(property);
|
||||
|
||||
results.addAll(Loader.loadScripts(
|
||||
new String[] { scriptToExecute }, timeOut));
|
||||
}
|
||||
} finally {
|
||||
property.setNumberOfImages(numberOfImages);
|
||||
property.setEntryQueryParameters(oldQuery, false);
|
||||
}
|
||||
|
||||
return wrapRawRecord(results);
|
||||
}
|
||||
|
||||
protected abstract List<AbstractRequestableData> wrapRawRecord(
|
||||
List<Object> objs) throws VizException;
|
||||
|
||||
protected List<Map<String, RequestConstraint>> merge(
|
||||
List<AbstractRequestableLevelNode> requests) {
|
||||
List<Map<String, RequestConstraint>> mergeMaps = new ArrayList<Map<String, RequestConstraint>>(
|
||||
requests.size());
|
||||
Iterator<AbstractRequestableLevelNode> iter = requests.iterator();
|
||||
while (iter.hasNext()) {
|
||||
AbstractRequestableLevelNode request = iter.next();
|
||||
if (request.hasRequestConstraints()) {
|
||||
mergeMaps.add(request.getRequestConstraintMap());
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
return mergeConstraints(mergeMaps);
|
||||
return two;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -390,7 +204,7 @@ public abstract class AbstractCubeLevelNode extends AbstractDerivedLevelNode {
|
|||
public List<Dependency> getDependencies() {
|
||||
List<Dependency> dependencies = new ArrayList<Dependency>(
|
||||
levels.size() * 2);
|
||||
for (CubeLevel<AbstractRequestableLevelNode, AbstractRequestableLevelNode> level : levels) {
|
||||
for (CubeLevel<AbstractRequestableNode, AbstractRequestableNode> level : levels) {
|
||||
dependencies.add(new Dependency(level.getPressure(), 0));
|
||||
dependencies.add(new Dependency(level.getParam(), 0));
|
||||
}
|
||||
|
|
|
@ -24,15 +24,10 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.responses.DbQueryResponse;
|
||||
import com.raytheon.uf.common.derivparam.tree.LevelNode;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
|
||||
|
@ -55,8 +50,7 @@ import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
|||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public abstract class AbstractDerivedLevelNode extends
|
||||
AbstractRequestableLevelNode {
|
||||
public abstract class AbstractDerivedDataNode extends AbstractRequestableNode {
|
||||
|
||||
protected DerivParamDesc desc;
|
||||
|
||||
|
@ -64,15 +58,15 @@ public abstract class AbstractDerivedLevelNode extends
|
|||
|
||||
protected String modelName;
|
||||
|
||||
public AbstractDerivedLevelNode() {
|
||||
public AbstractDerivedDataNode() {
|
||||
}
|
||||
|
||||
public AbstractDerivedLevelNode(Level level, DerivParamDesc desc,
|
||||
public AbstractDerivedDataNode(Level level, DerivParamDesc desc,
|
||||
String modelName) {
|
||||
this(level, desc, null, modelName);
|
||||
}
|
||||
|
||||
public AbstractDerivedLevelNode(Level level, DerivParamDesc desc,
|
||||
public AbstractDerivedDataNode(Level level, DerivParamDesc desc,
|
||||
DerivParamMethod method, String modelName) {
|
||||
super(level);
|
||||
this.desc = desc;
|
||||
|
@ -80,7 +74,7 @@ public abstract class AbstractDerivedLevelNode extends
|
|||
this.modelName = modelName;
|
||||
}
|
||||
|
||||
public AbstractDerivedLevelNode(LevelNode that, DerivParamDesc desc,
|
||||
public AbstractDerivedDataNode(LevelNode that, DerivParamDesc desc,
|
||||
DerivParamMethod method, String modelName) {
|
||||
super(that);
|
||||
this.desc = desc;
|
||||
|
@ -88,7 +82,7 @@ public abstract class AbstractDerivedLevelNode extends
|
|||
this.modelName = modelName;
|
||||
}
|
||||
|
||||
public AbstractDerivedLevelNode(AbstractDerivedLevelNode that) {
|
||||
public AbstractDerivedDataNode(AbstractDerivedDataNode that) {
|
||||
super(that);
|
||||
this.desc = that.desc;
|
||||
this.method = that.method;
|
||||
|
@ -133,16 +127,6 @@ public abstract class AbstractDerivedLevelNode extends
|
|||
this.method = method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, RequestConstraint> getRequestConstraintMap() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRequestConstraints() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the vector, abbreviation, name, unit, and level to match the desc
|
||||
* and level in this node
|
||||
|
@ -191,7 +175,7 @@ public abstract class AbstractDerivedLevelNode extends
|
|||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
AbstractDerivedLevelNode other = (AbstractDerivedLevelNode) obj;
|
||||
AbstractDerivedDataNode other = (AbstractDerivedDataNode) obj;
|
||||
if (desc == null) {
|
||||
if (other.desc != null)
|
||||
return false;
|
||||
|
@ -211,43 +195,54 @@ public abstract class AbstractDerivedLevelNode extends
|
|||
}
|
||||
|
||||
/**
|
||||
* Should only be called on final nodes, not derived nodes.
|
||||
* Given the availability of all dependency nodes determine when this node
|
||||
* is available.
|
||||
*
|
||||
* @param availability
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
@Override
|
||||
protected DbQueryRequest getDataQueryInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException {
|
||||
throw new UnsupportedOperationException(
|
||||
"Derived nodes do not support retrieving data query, call on dependencies");
|
||||
}
|
||||
public abstract Set<TimeAndSpace> getAvailability(
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> availability)
|
||||
throws VizException;
|
||||
|
||||
/**
|
||||
* Should only be called on final nodes, not derived nodes.
|
||||
* If this node has dependency on other nodes then this method should return
|
||||
* what data is needed for the dependencies to get data from this node for
|
||||
* the provided availability.
|
||||
*
|
||||
* @param availability
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void setDataQueryResults(
|
||||
DbQueryResponse queryResponse,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException {
|
||||
throw new UnsupportedOperationException(
|
||||
"Derived nodes do not support processing data query, call on dependencies");
|
||||
}
|
||||
public abstract Map<AbstractRequestableNode, Set<TimeAndSpace>> getDataDependency(
|
||||
Set<TimeAndSpace> availability) throws VizException;
|
||||
|
||||
/**
|
||||
* Get data from this node.
|
||||
*
|
||||
* @param availability
|
||||
* The time and spatial area where data is needed
|
||||
* @return
|
||||
*/
|
||||
public abstract Set<AbstractRequestableData> getData(
|
||||
Set<TimeAndSpace> availability,
|
||||
Map<AbstractRequestableNode, Set<AbstractRequestableData>> dependencyData)
|
||||
throws VizException;
|
||||
|
||||
public abstract List<Dependency> getDependencies();
|
||||
|
||||
@Override
|
||||
protected List<AbstractRequestableData> processDataQueryResults(
|
||||
DbQueryResponse queryResponse) throws VizException {
|
||||
throw new UnsupportedOperationException(
|
||||
"Derived nodes do not support processing data query, call on dependencies");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TimeQueryRequest getTimeQueryInternal(
|
||||
TimeQueryRequest originalRequest, boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache)
|
||||
throws VizException {
|
||||
throw new UnsupportedOperationException(
|
||||
"Derived nodes do not support retrieving time query, call on dependencies");
|
||||
public boolean isConstant() {
|
||||
List<Dependency> dependencies = getDependencies();
|
||||
if (dependencies.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (Dependency dep : getDependencies()) {
|
||||
if (!dep.node.isConstant()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// All dependencies must be constant
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,421 +0,0 @@
|
|||
/**
|
||||
* 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.viz.derivparam.tree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.responses.DbQueryResponse;
|
||||
import com.raytheon.uf.common.derivparam.tree.LevelNode;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
|
||||
/**
|
||||
*
|
||||
* The base level node for Cave, each Level Node should be able to handle time
|
||||
* queries and metadata requests. This class attempts to handle
|
||||
* caching(currently very limited) for all subclasses.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jan 19, 2010 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public abstract class AbstractRequestableLevelNode extends LevelNode {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static final Set<DataTime> TIME_AGNOSTIC = Collections.EMPTY_SET;
|
||||
|
||||
public static class Dependency {
|
||||
|
||||
public Dependency(AbstractRequestableLevelNode node, int timeOffset) {
|
||||
super();
|
||||
this.node = node;
|
||||
this.timeOffset = timeOffset;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((node == null) ? 0 : node.hashCode());
|
||||
result = prime * result + timeOffset;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Dependency other = (Dependency) obj;
|
||||
if (node == null) {
|
||||
if (other.node != null)
|
||||
return false;
|
||||
} else if (!node.equals(other.node))
|
||||
return false;
|
||||
if (timeOffset != other.timeOffset)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public AbstractRequestableLevelNode node;
|
||||
|
||||
public int timeOffset;
|
||||
}
|
||||
|
||||
public AbstractRequestableLevelNode() {
|
||||
}
|
||||
|
||||
public AbstractRequestableLevelNode(Level level) {
|
||||
super(level);
|
||||
}
|
||||
|
||||
public AbstractRequestableLevelNode(LevelNode that) {
|
||||
super(that);
|
||||
}
|
||||
|
||||
public List<AbstractRequestableData> getData(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException {
|
||||
DataTime[] origTimes = property.getSelectedEntryTime();
|
||||
List<AbstractRequestableData> rval = new ArrayList<AbstractRequestableData>();
|
||||
if (cache != null && cache.containsKey(this) && origTimes != null) {
|
||||
List<AbstractRequestableData> cachedRecords = cache.get(this);
|
||||
List<DataTime> selectedTimes = Arrays.asList(origTimes);
|
||||
List<DataTime> newTimes = new ArrayList<DataTime>(selectedTimes);
|
||||
for (AbstractRequestableData record : cachedRecords) {
|
||||
if (selectedTimes.contains(record.getDataTime())) {
|
||||
rval.add(record);
|
||||
newTimes.remove(record.getDataTime());
|
||||
}
|
||||
}
|
||||
property.setSelectedEntryTimes(newTimes.toArray(new DataTime[0]));
|
||||
}
|
||||
if (origTimes == null || property.getSelectedEntryTime().length > 0) {
|
||||
List<AbstractRequestableData> newRecords = getDataInternal(
|
||||
property, timeOut, cache);
|
||||
rval.addAll(newRecords);
|
||||
List<AbstractRequestableData> cachedRecords = cache.get(this);
|
||||
if (cachedRecords == null) {
|
||||
cache.put(this, new ArrayList<AbstractRequestableData>(
|
||||
newRecords));
|
||||
} else {
|
||||
cachedRecords.addAll(newRecords);
|
||||
}
|
||||
}
|
||||
property.setSelectedEntryTimes(origTimes);
|
||||
return rval;
|
||||
}
|
||||
|
||||
public DbQueryRequest getDataQuery(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException {
|
||||
DataTime[] origTimes = property.getSelectedEntryTime();
|
||||
DbQueryRequest rval = null;
|
||||
if (cache != null && cache.containsKey(this) && origTimes != null) {
|
||||
List<AbstractRequestableData> cachedRecords = cache.get(this);
|
||||
List<DataTime> selectedTimes = Arrays.asList(origTimes);
|
||||
List<DataTime> newTimes = new ArrayList<DataTime>(selectedTimes);
|
||||
for (AbstractRequestableData record : cachedRecords) {
|
||||
if (selectedTimes.contains(record.getDataTime())) {
|
||||
newTimes.remove(record.getDataTime());
|
||||
}
|
||||
}
|
||||
property.setSelectedEntryTimes(newTimes
|
||||
.toArray(new DataTime[newTimes.size()]));
|
||||
}
|
||||
if (origTimes == null || property.getSelectedEntryTime().length > 0) {
|
||||
rval = getDataQueryInternal(property, timeOut, cache);
|
||||
}
|
||||
property.setSelectedEntryTimes(origTimes);
|
||||
return rval;
|
||||
}
|
||||
|
||||
public void setDataQueryResults(
|
||||
DbQueryResponse queryResponse,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException {
|
||||
// need transform method
|
||||
List<AbstractRequestableData> records = processDataQueryResults(queryResponse);
|
||||
if (records == null || records.size() > 0) {
|
||||
List<AbstractRequestableData> cachedRecords = cache.get(this);
|
||||
if (cachedRecords == null) {
|
||||
cache.put(this, records);
|
||||
} else {
|
||||
// dups?
|
||||
cachedRecords.addAll(records);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract List<AbstractRequestableData> processDataQueryResults(
|
||||
DbQueryResponse queryResponse) throws VizException;
|
||||
|
||||
public Set<DataTime> timeQuery(TimeQueryRequest originalRequest,
|
||||
boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
throws VizException {
|
||||
if (cache != null && cache.containsKey(this)) {
|
||||
return cache.get(this);
|
||||
} else if (latestOnly && latestOnlyCache.containsKey(this)) {
|
||||
return latestOnlyCache.get(this);
|
||||
}
|
||||
|
||||
Set<DataTime> results = timeQueryInternal(originalRequest, latestOnly,
|
||||
cache, latestOnlyCache);
|
||||
if (cache != null && !latestOnly) {
|
||||
cache.put(this, results);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public TimeQueryRequest getTimeQuery(TimeQueryRequest originalRequest,
|
||||
boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
throws VizException {
|
||||
if (cache != null && cache.containsKey(this)) {
|
||||
return null;
|
||||
} else if (latestOnly && latestOnlyCache.containsKey(this)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getTimeQueryInternal(originalRequest, latestOnly, cache);
|
||||
}
|
||||
|
||||
public void setTimeQueryResults(boolean latestOnly,
|
||||
List<DataTime> queryResponse,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
throws VizException {
|
||||
// perform any node specific processing
|
||||
processTimeQueryResults(latestOnly, queryResponse);
|
||||
if (latestOnly) {
|
||||
Set<DataTime> cachedRecords = latestOnlyCache.get(this);
|
||||
if (cachedRecords == null) {
|
||||
latestOnlyCache.put(this, new HashSet<DataTime>(queryResponse));
|
||||
} else {
|
||||
cachedRecords.addAll(queryResponse);
|
||||
}
|
||||
} else {
|
||||
Set<DataTime> cachedRecords = cache.get(this);
|
||||
if (cachedRecords == null) {
|
||||
cache.put(this, new HashSet<DataTime>(queryResponse));
|
||||
} else {
|
||||
cachedRecords.addAll(queryResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void processTimeQueryResults(boolean latestOnly,
|
||||
List<DataTime> queryResponse) throws VizException {
|
||||
// default has no internal processing to add
|
||||
}
|
||||
|
||||
public abstract List<Dependency> getDependencies();
|
||||
|
||||
public abstract boolean isTimeAgnostic();
|
||||
|
||||
public abstract boolean hasRequestConstraints();
|
||||
|
||||
public abstract Map<String, RequestConstraint> getRequestConstraintMap();
|
||||
|
||||
public boolean isConstant() {
|
||||
List<Dependency> dependencies = getDependencies();
|
||||
if (dependencies.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (Dependency dep : getDependencies()) {
|
||||
if (!dep.node.isConstant()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// All dependencies must be constant
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the list of constraintMaps and merges the constraint maps that
|
||||
* different by only one key into a new list of constraint maps. EX: 5
|
||||
* RequestConstraint Maps for GFS40 Temp on 5 MB levels will be consolidated
|
||||
* into a single RequestConstraint Map using an IN List for the MB levels.
|
||||
*
|
||||
* @param constraintMaps
|
||||
* @return
|
||||
*/
|
||||
public List<Map<String, RequestConstraint>> mergeConstraints(
|
||||
List<Map<String, RequestConstraint>> constraintMaps) {
|
||||
List<Map<String, RequestConstraint>> rval = new ArrayList<Map<String, RequestConstraint>>();
|
||||
if (constraintMaps != null && constraintMaps.size() > 0) {
|
||||
List<String> mergeKeyList = new ArrayList<String>();
|
||||
|
||||
for (Map<String, RequestConstraint> constraintMap : constraintMaps) {
|
||||
boolean merged = false;
|
||||
int index = 0;
|
||||
|
||||
MERGE_MAP_LOOP: for (index = 0; index < rval.size(); index++) {
|
||||
Map<String, RequestConstraint> mergeMap = rval.get(index);
|
||||
|
||||
// maps must be of same size
|
||||
if (mergeMap.size() == constraintMap.size()) {
|
||||
String mergeKey = mergeKeyList.get(index);
|
||||
|
||||
if (mergeKey != null) {
|
||||
// determine if it matches map except for uniqueKey
|
||||
for (String key : mergeMap.keySet()) {
|
||||
boolean isUniqueKey = mergeKey.equals(key);
|
||||
boolean constraintEquals = mergeMap.get(key)
|
||||
.equals(constraintMap.get(key));
|
||||
|
||||
if (!constraintEquals && !isUniqueKey) {
|
||||
continue MERGE_MAP_LOOP;
|
||||
}
|
||||
}
|
||||
|
||||
// map differs except for key
|
||||
boolean constraintMerged = mergeMap.get(mergeKey)
|
||||
.merge(constraintMap.get(mergeKey));
|
||||
if (!constraintMerged) {
|
||||
continue MERGE_MAP_LOOP;
|
||||
} else {
|
||||
merged = true;
|
||||
break MERGE_MAP_LOOP;
|
||||
}
|
||||
} else {
|
||||
// current mergeMap has never been merged with,
|
||||
// double check that only one key is different
|
||||
// between maps
|
||||
for (String key : mergeMap.keySet()) {
|
||||
if (!mergeMap.get(key).equals(
|
||||
constraintMap.get(key))) {
|
||||
if (mergeKey == null) {
|
||||
// possible merge key, continue checking
|
||||
// map
|
||||
mergeKey = key;
|
||||
} else {
|
||||
// two merge keys found, go to next
|
||||
// merge map
|
||||
continue MERGE_MAP_LOOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
merged = true;
|
||||
|
||||
// found mergeKey, add to mergeKeyList. If mergeKey
|
||||
// still being null is only possible of mergeMap and
|
||||
// constraintMap contain the exact same constraints,
|
||||
// consider them merged
|
||||
if (mergeKey != null) {
|
||||
mergeKeyList.set(index, mergeKey);
|
||||
}
|
||||
|
||||
break MERGE_MAP_LOOP;
|
||||
}
|
||||
} // maps same size check
|
||||
} // MERGE_MAP_LOOP
|
||||
|
||||
if (!merged) {
|
||||
Map<String, RequestConstraint> mergeMap = new HashMap<String, RequestConstraint>();
|
||||
|
||||
// deep copy the map
|
||||
for (Map.Entry<String, RequestConstraint> entry : constraintMap
|
||||
.entrySet()) {
|
||||
mergeMap.put(entry.getKey(), entry.getValue().clone());
|
||||
}
|
||||
|
||||
rval.add(mergeMap);
|
||||
mergeKeyList.add(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
protected abstract Set<DataTime> timeQueryInternal(
|
||||
TimeQueryRequest originalRequest, boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
throws VizException;
|
||||
|
||||
protected abstract TimeQueryRequest getTimeQueryInternal(
|
||||
TimeQueryRequest originalRequest, boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache)
|
||||
throws VizException;
|
||||
|
||||
protected abstract List<AbstractRequestableData> getDataInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException;
|
||||
|
||||
protected abstract DbQueryRequest getDataQueryInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException;
|
||||
|
||||
protected Set<DataTime> timeQuery(TimeQueryRequest originalRequest,
|
||||
boolean latestOnly) throws VizException {
|
||||
return timeQuery(originalRequest, latestOnly,
|
||||
new HashMap<AbstractRequestableLevelNode, Set<DataTime>>(),
|
||||
new HashMap<AbstractRequestableLevelNode, Set<DataTime>>());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/**
|
||||
* 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.viz.derivparam.tree;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.derivparam.tree.LevelNode;
|
||||
|
||||
/**
|
||||
*
|
||||
* The base level node for Cave, each Level Node should be able to handle time
|
||||
* queries and metadata requests. This class attempts to handle
|
||||
* caching(currently very limited) for all subclasses.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jan 19, 2010 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public abstract class AbstractRequestableNode extends LevelNode {
|
||||
|
||||
public static class Dependency {
|
||||
|
||||
public Dependency(AbstractRequestableNode node, int timeOffset) {
|
||||
super();
|
||||
this.node = node;
|
||||
this.timeOffset = timeOffset;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((node == null) ? 0 : node.hashCode());
|
||||
result = prime * result + timeOffset;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Dependency other = (Dependency) obj;
|
||||
if (node == null) {
|
||||
if (other.node != null)
|
||||
return false;
|
||||
} else if (!node.equals(other.node))
|
||||
return false;
|
||||
if (timeOffset != other.timeOffset)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public AbstractRequestableNode node;
|
||||
|
||||
public int timeOffset;
|
||||
}
|
||||
|
||||
public AbstractRequestableNode() {
|
||||
}
|
||||
|
||||
public AbstractRequestableNode(Level level) {
|
||||
super(level);
|
||||
}
|
||||
|
||||
public AbstractRequestableNode(LevelNode that) {
|
||||
super(that);
|
||||
}
|
||||
|
||||
public abstract boolean isConstant();
|
||||
|
||||
}
|
|
@ -19,15 +19,15 @@
|
|||
**/
|
||||
package com.raytheon.uf.viz.derivparam.tree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.data.AliasRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
|
||||
|
@ -56,20 +56,19 @@ public class AliasLevelNode extends AbstractAliasLevelNode {
|
|||
super(that);
|
||||
}
|
||||
|
||||
public AliasLevelNode(AbstractRequestableLevelNode sourceNode,
|
||||
public AliasLevelNode(AbstractRequestableNode sourceNode,
|
||||
DerivParamDesc desc, DerivParamMethod method, String modelName,
|
||||
Level level) {
|
||||
super(sourceNode, desc, method, modelName, level);
|
||||
}
|
||||
|
||||
public List<AbstractRequestableData> getDataInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
@Override
|
||||
public Set<AbstractRequestableData> getData(
|
||||
Set<TimeAndSpace> availability,
|
||||
Map<AbstractRequestableNode, Set<AbstractRequestableData>> dependencyData)
|
||||
throws VizException {
|
||||
List<AbstractRequestableData> origs = sourceNode.getData(property,
|
||||
timeOut, cache);
|
||||
List<AbstractRequestableData> results = new ArrayList<AbstractRequestableData>(
|
||||
Set<AbstractRequestableData> origs = dependencyData.get(sourceNode);
|
||||
Set<AbstractRequestableData> results = new HashSet<AbstractRequestableData>(
|
||||
origs.size());
|
||||
for (AbstractRequestableData orig : origs) {
|
||||
AbstractRequestableData result = new AliasRequestableData(orig);
|
||||
|
|
|
@ -26,13 +26,11 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequest;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.data.AggregateRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.data.DerivedRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivedParameterRequest;
|
||||
|
||||
|
@ -64,19 +62,19 @@ public class CompositeAverageLevelNode extends UnionLevelNode {
|
|||
}
|
||||
|
||||
public CompositeAverageLevelNode(Level level, DerivParamDesc desc,
|
||||
String modelName, List<AbstractRequestableLevelNode> nodes) {
|
||||
String modelName, List<AbstractRequestableNode> nodes) {
|
||||
super(level, desc, null, modelName, nodes);
|
||||
}
|
||||
|
||||
public List<AbstractRequestableData> getDataInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
@Override
|
||||
public Set<AbstractRequestableData> getData(
|
||||
Set<TimeAndSpace> availability,
|
||||
Map<AbstractRequestableNode, Set<AbstractRequestableData>> dependencyData)
|
||||
throws VizException {
|
||||
List<AbstractRequestableData> result = new ArrayList<AbstractRequestableData>();
|
||||
Set<AbstractRequestableData> result = new HashSet<AbstractRequestableData>();
|
||||
|
||||
for (AbstractRequestableData record : super.getDataInternal(property,
|
||||
timeOut, cache)) {
|
||||
for (AbstractRequestableData record : super.getData(availability,
|
||||
dependencyData)) {
|
||||
AggregateRequestableData aRec = (AggregateRequestableData) record;
|
||||
if (aRec.getSourceRecords().size() == nodes.size()) {
|
||||
DerivedParameterRequest request = new DerivedParameterRequest();
|
||||
|
@ -95,33 +93,22 @@ public class CompositeAverageLevelNode extends UnionLevelNode {
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.viz.derivparam.tree.UnionLevelNode#timeQueryInternal(
|
||||
* boolean, java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
public Set<DataTime> timeQueryInternal(TimeQueryRequest originalRequest,
|
||||
boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
public Set<TimeAndSpace> getAvailability(
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> availability)
|
||||
throws VizException {
|
||||
// We should only have times if all our nodes have times
|
||||
Set<DataTime> results = TIME_AGNOSTIC;
|
||||
Set<TimeAndSpace> results = null;
|
||||
|
||||
List<AbstractRequestableLevelNode> requests = new ArrayList<AbstractRequestableLevelNode>(
|
||||
List<AbstractRequestableNode> requests = new ArrayList<AbstractRequestableNode>(
|
||||
nodes);
|
||||
for (AbstractRequestableLevelNode request : requests) {
|
||||
for (AbstractRequestableNode request : requests) {
|
||||
// Do not request just latest only because if two nodes have
|
||||
// different latests than this will return no times
|
||||
Set<DataTime> times = request.timeQuery(originalRequest, false,
|
||||
cache, latestOnlyCache);
|
||||
if (times == TIME_AGNOSTIC) {
|
||||
Set<TimeAndSpace> times = availability.get(request);
|
||||
if (times == null) {
|
||||
continue;
|
||||
} else if (results == TIME_AGNOSTIC) {
|
||||
results = new HashSet<DataTime>(times);
|
||||
} else if (results == null) {
|
||||
results = new HashSet<TimeAndSpace>(times);
|
||||
} else {
|
||||
results.retainAll(times);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ package com.raytheon.uf.viz.derivparam.tree;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
@ -32,14 +33,15 @@ import java.util.Map.Entry;
|
|||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequest;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.common.time.DataTime.FLAG;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.data.AliasRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.data.DerivedRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.AvailabilityContainer;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpaceMatcher;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpaceMatcher.MatchResult;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamField;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
|
@ -64,19 +66,19 @@ import com.raytheon.uf.viz.derivparam.library.IDerivParamField;
|
|||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class DerivedLevelNode extends AbstractDerivedLevelNode {
|
||||
public class DerivedLevelNode extends AbstractDerivedDataNode {
|
||||
|
||||
private static final int TIME_QUERY_CACHE_TIME = 30000;
|
||||
|
||||
private Map<IDerivParamField, AbstractRequestableData> fieldStaticData = null;
|
||||
|
||||
private Map<DerivParamField, AbstractRequestableLevelNode> fields = null;
|
||||
private Map<DerivParamField, AbstractRequestableNode> fields = null;
|
||||
|
||||
/**
|
||||
* Time cache should be reset every time a time query is performed and then
|
||||
* it can be used to correlate times when requesting data.
|
||||
*/
|
||||
private Map<DerivParamField, Set<DataTime>> timeCache = null;
|
||||
private Map<DerivParamField, Set<TimeAndSpace>> availCache = null;
|
||||
|
||||
private long lastTimeQuery = 0;
|
||||
|
||||
|
@ -91,7 +93,7 @@ public class DerivedLevelNode extends AbstractDerivedLevelNode {
|
|||
public DerivedLevelNode(DerivedLevelNode that) {
|
||||
super(that);
|
||||
if (that.fields != null) {
|
||||
fields = new HashMap<DerivParamField, AbstractRequestableLevelNode>(
|
||||
fields = new HashMap<DerivParamField, AbstractRequestableNode>(
|
||||
that.fields);
|
||||
}
|
||||
if (that.fieldStaticData != null) {
|
||||
|
@ -111,7 +113,7 @@ public class DerivedLevelNode extends AbstractDerivedLevelNode {
|
|||
/**
|
||||
* @return the fields
|
||||
*/
|
||||
public Map<DerivParamField, AbstractRequestableLevelNode> getFields() {
|
||||
public Map<DerivParamField, AbstractRequestableNode> getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
|
@ -130,10 +132,9 @@ public class DerivedLevelNode extends AbstractDerivedLevelNode {
|
|||
this.fieldStaticData.put(field, requestableData);
|
||||
}
|
||||
|
||||
public void putField(DerivParamField field,
|
||||
AbstractRequestableLevelNode object) {
|
||||
public void putField(DerivParamField field, AbstractRequestableNode object) {
|
||||
if (fields == null) {
|
||||
fields = new HashMap<DerivParamField, AbstractRequestableLevelNode>();
|
||||
fields = new HashMap<DerivParamField, AbstractRequestableNode>();
|
||||
}
|
||||
this.fields.put(field, object);
|
||||
}
|
||||
|
@ -149,99 +150,75 @@ public class DerivedLevelNode extends AbstractDerivedLevelNode {
|
|||
return getFieldsSize() == method.getFields().size();
|
||||
}
|
||||
|
||||
private TimeAndSpaceMatcher getMatcher() {
|
||||
TimeAndSpaceMatcher matcher = new TimeAndSpaceMatcher();
|
||||
matcher.setIgnoreRange(true);
|
||||
if (method.isFtime()) {
|
||||
matcher.setMatchValid(false);
|
||||
} else {
|
||||
matcher.setMatchValid(true);
|
||||
}
|
||||
return matcher;
|
||||
}
|
||||
|
||||
private Map<TimeAndSpace, TimeAndSpace> shiftTime(DerivParamField field,
|
||||
Set<TimeAndSpace> dataTimes) {
|
||||
int timeShift = getDTimeInSeconds(field);
|
||||
if (timeShift != 0) {
|
||||
Map<TimeAndSpace, TimeAndSpace> result = new HashMap<TimeAndSpace, TimeAndSpace>();
|
||||
for (TimeAndSpace t : dataTimes) {
|
||||
if (t.isTimeAgnostic()) {
|
||||
result.put(t, t);
|
||||
} else {
|
||||
DataTime time = t.getTime();
|
||||
long rTime = time.getRefTime().getTime();
|
||||
int fTime = time.getFcstTime();
|
||||
// Shift valid time back rather than having a
|
||||
// negative forecast time.
|
||||
fTime -= timeShift;
|
||||
while (method.isDtime() && fTime < 0) {
|
||||
rTime -= dt * 1000;
|
||||
fTime += dt;
|
||||
}
|
||||
time = new DataTime(new Date(rTime), fTime);
|
||||
result.put(new TimeAndSpace(time, t.getSpace()), t);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<DataTime> timeQueryInternal(TimeQueryRequest originalRequest,
|
||||
boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
public Set<TimeAndSpace> getAvailability(
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> availability)
|
||||
throws VizException {
|
||||
this.lastTimeQuery = System.currentTimeMillis();
|
||||
Map<DerivParamField, Set<DataTime>> timeCache = new HashMap<DerivParamField, Set<DataTime>>();
|
||||
TimeAndSpaceMatcher matcher = getMatcher();
|
||||
Map<DerivParamField, Set<TimeAndSpace>> availCache = new HashMap<DerivParamField, Set<TimeAndSpace>>();
|
||||
// We have a derived parameter for the requested grid
|
||||
Set<DataTime> availableDataTimes = null;
|
||||
Set<TimeAndSpace> availableDataTimes = null;
|
||||
if (fields == null) {
|
||||
timeCache.put(null, TIME_AGNOSTIC);
|
||||
this.timeCache = timeCache;
|
||||
return TIME_AGNOSTIC;
|
||||
availableDataTimes = AvailabilityContainer.AGNOSTIC_SET;
|
||||
availCache.put(null, availableDataTimes);
|
||||
this.availCache = availCache;
|
||||
return availableDataTimes;
|
||||
}
|
||||
Collection<DerivParamField> fieldsKeys = fields.keySet();
|
||||
if (method.isDtime()) {
|
||||
// Attempt to use 0 time shift data first.
|
||||
List<DerivParamField> fieldsList = new ArrayList<DerivParamField>(
|
||||
fieldsKeys);
|
||||
for (int i = 1; i < fieldsList.size(); i++) {
|
||||
if (fieldsList.get(i).getTimeShift() == 0) {
|
||||
fieldsList.set(i, fieldsList.set(0, fieldsList.get(i)));
|
||||
}
|
||||
}
|
||||
fieldsKeys = fieldsList;
|
||||
}
|
||||
for (DerivParamField field : fieldsKeys) {
|
||||
AbstractRequestableLevelNode node = fields.get(field);
|
||||
Set<DataTime> queryDataTimes = node.timeQuery(originalRequest,
|
||||
false, cache, latestOnlyCache);
|
||||
timeCache.put(field, queryDataTimes);
|
||||
if (queryDataTimes == TIME_AGNOSTIC) {
|
||||
if (availableDataTimes == null) {
|
||||
availableDataTimes = TIME_AGNOSTIC;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for (DerivParamField field : fields.keySet()) {
|
||||
AbstractRequestableNode node = fields.get(field);
|
||||
Set<TimeAndSpace> queryDataTimes = availability.get(node);
|
||||
availCache.put(field, queryDataTimes);
|
||||
if (queryDataTimes != null && queryDataTimes.size() > 0) {
|
||||
|
||||
if (availableDataTimes != null
|
||||
&& availableDataTimes != TIME_AGNOSTIC) {
|
||||
availableDataTimes.retainAll(timeMatch(availableDataTimes,
|
||||
queryDataTimes, field).keySet());
|
||||
} else {
|
||||
// populate initial data times
|
||||
|
||||
if (method.isDtime()) {
|
||||
// if dT required handle now
|
||||
int dTimeInSeconds = getDTimeInSeconds(field);
|
||||
|
||||
if (dTimeInSeconds == -1) {
|
||||
return new HashSet<DataTime>(0);
|
||||
}
|
||||
|
||||
// handle valid time shift
|
||||
availableDataTimes = new HashSet<DataTime>((64));
|
||||
|
||||
// generate all possible valid times
|
||||
for (DataTime dataTime : queryDataTimes) {
|
||||
if (field.getTimeShift() == 0) {
|
||||
// Strip any validPeriodInfo
|
||||
availableDataTimes.add(new DataTime(dataTime
|
||||
.getRefTime(), dataTime.getFcstTime()));
|
||||
} else {
|
||||
availableDataTimes
|
||||
.addAll(generatePossibleDataTimes(
|
||||
dataTime, field));
|
||||
}
|
||||
}
|
||||
} else if (method.isFtime()) {
|
||||
// handle forecast time shift
|
||||
availableDataTimes = new HashSet<DataTime>();
|
||||
int fcstShift = field.getTimeShift();
|
||||
for (DataTime dataTime : queryDataTimes) {
|
||||
int fcstTime = dataTime.getFcstTime() - fcstShift;
|
||||
if (fcstTime >= 0) {
|
||||
availableDataTimes.add(new DataTime(dataTime
|
||||
.getRefTime(), fcstTime));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
availableDataTimes = new HashSet<DataTime>();
|
||||
for (DataTime time : queryDataTimes) {
|
||||
if (time.getUtilityFlags().contains(FLAG.FCST_USED))
|
||||
availableDataTimes.add(new DataTime(time
|
||||
.getRefTime(), time.getFcstTime()));
|
||||
else
|
||||
availableDataTimes.add(new DataTime(time
|
||||
.getRefTime()));
|
||||
}
|
||||
}
|
||||
Map<TimeAndSpace, TimeAndSpace> shiftMap = shiftTime(field,
|
||||
queryDataTimes);
|
||||
if (shiftMap != null) {
|
||||
queryDataTimes = shiftMap.keySet();
|
||||
}
|
||||
if (availableDataTimes == null) {
|
||||
availableDataTimes = AvailabilityContainer.AGNOSTIC_SET;
|
||||
}
|
||||
availableDataTimes = matcher.match(availableDataTimes,
|
||||
queryDataTimes).keySet();
|
||||
} else {
|
||||
// no data for this query, clear times and return
|
||||
availableDataTimes = null;
|
||||
|
@ -254,71 +231,100 @@ public class DerivedLevelNode extends AbstractDerivedLevelNode {
|
|||
}// FIELD_LOOP
|
||||
|
||||
if (availableDataTimes != null) {
|
||||
timeCache.put(null, availableDataTimes);
|
||||
this.timeCache = timeCache;
|
||||
availCache.put(null, availableDataTimes);
|
||||
this.availCache = availCache;
|
||||
} else {
|
||||
timeCache = new HashMap<DerivParamField, Set<DataTime>>();
|
||||
availableDataTimes = new HashSet<DataTime>(0);
|
||||
timeCache.put(null, availableDataTimes);
|
||||
this.timeCache = timeCache;
|
||||
availCache = new HashMap<DerivParamField, Set<TimeAndSpace>>();
|
||||
availableDataTimes = new HashSet<TimeAndSpace>(0);
|
||||
availCache.put(null, availableDataTimes);
|
||||
this.availCache = availCache;
|
||||
}
|
||||
return availableDataTimes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTimeAgnostic() {
|
||||
boolean timeAgnostic = true;
|
||||
|
||||
for (AbstractRequestableLevelNode node : fields.values()) {
|
||||
if (!node.isTimeAgnostic()) {
|
||||
timeAgnostic = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return timeAgnostic;
|
||||
}
|
||||
|
||||
public List<AbstractRequestableData> getDataInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException {
|
||||
if (this.timeCache == null
|
||||
public Map<AbstractRequestableNode, Set<TimeAndSpace>> getDataDependency(
|
||||
Set<TimeAndSpace> availability) throws VizException {
|
||||
if (this.availCache == null
|
||||
|| this.lastTimeQuery + TIME_QUERY_CACHE_TIME < System
|
||||
.currentTimeMillis()) {
|
||||
this.timeQuery(null, false);
|
||||
new AvailabilityContainer().getAvailability(this);
|
||||
}
|
||||
|
||||
// keep a reference for scope of method
|
||||
Map<DerivParamField, Set<DataTime>> myTimeCache = this.timeCache;
|
||||
Set<DataTime> thisAvailableTimes = myTimeCache.get(null);
|
||||
if (thisAvailableTimes == TIME_AGNOSTIC) {
|
||||
thisAvailableTimes = new HashSet<DataTime>();
|
||||
thisAvailableTimes.add(null);
|
||||
} else {
|
||||
if (property.getSelectedEntryTime() != null) {
|
||||
thisAvailableTimes = new HashSet<DataTime>(thisAvailableTimes);
|
||||
thisAvailableTimes.retainAll(Arrays.asList(property
|
||||
.getSelectedEntryTime()));
|
||||
TimeAndSpaceMatcher matcher = getMatcher();
|
||||
Map<DerivParamField, Set<TimeAndSpace>> availCache = this.availCache;
|
||||
availability = matcher.match(availability, availCache.get(null))
|
||||
.keySet();
|
||||
if (availability.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> result = new HashMap<AbstractRequestableNode, Set<TimeAndSpace>>();
|
||||
if (fields != null) {
|
||||
for (Entry<DerivParamField, AbstractRequestableNode> field : fields
|
||||
.entrySet()) {
|
||||
Set<TimeAndSpace> queryTimes = availCache.get(field.getKey());
|
||||
Map<TimeAndSpace, TimeAndSpace> shiftMap = shiftTime(
|
||||
field.getKey(), queryTimes);
|
||||
if (shiftMap != null) {
|
||||
queryTimes = shiftMap.keySet();
|
||||
}
|
||||
Set<TimeAndSpace> fieldResult = TimeAndSpaceMatcher
|
||||
.getAll2(matcher.match(availability, queryTimes));
|
||||
if (shiftMap != null) {
|
||||
Set<TimeAndSpace> newFieldResult = new HashSet<TimeAndSpace>();
|
||||
for (TimeAndSpace t : fieldResult) {
|
||||
newFieldResult.add(shiftMap.get(t));
|
||||
}
|
||||
fieldResult = newFieldResult;
|
||||
}
|
||||
Set<TimeAndSpace> oldSet = result.put(field.getValue(),
|
||||
fieldResult);
|
||||
if (oldSet != null) {
|
||||
fieldResult.addAll(oldSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<DataTime, DerivedParameterRequest> mapOfRequests = new HashMap<DataTime, DerivedParameterRequest>(
|
||||
thisAvailableTimes.size());
|
||||
List<DerivedRequestableData> initResponses = new ArrayList<DerivedRequestableData>(
|
||||
thisAvailableTimes.size());
|
||||
if (fieldStaticData != null) {
|
||||
for (Entry<IDerivParamField, AbstractRequestableData> entry : fieldStaticData
|
||||
.entrySet()) {
|
||||
StaticDataLevelNode node = new StaticDataLevelNode(level, desc,
|
||||
entry.getValue(), modelName);
|
||||
result.put(node, AvailabilityContainer.AGNOSTIC_SET);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
for (DataTime time : thisAvailableTimes) {
|
||||
@Override
|
||||
public Set<AbstractRequestableData> getData(
|
||||
Set<TimeAndSpace> availability,
|
||||
Map<AbstractRequestableNode, Set<AbstractRequestableData>> dependencyData)
|
||||
throws VizException {
|
||||
if (this.availCache == null
|
||||
|| this.lastTimeQuery + TIME_QUERY_CACHE_TIME < System
|
||||
.currentTimeMillis()) {
|
||||
new AvailabilityContainer().getAvailability(this);
|
||||
}
|
||||
TimeAndSpaceMatcher matcher = getMatcher();
|
||||
Map<DerivParamField, Set<TimeAndSpace>> availCache = this.availCache;
|
||||
availability = matcher.match(availability, availCache.get(null))
|
||||
.keySet();
|
||||
Map<TimeAndSpace, DerivedParameterRequest> mapOfRequests = new HashMap<TimeAndSpace, DerivedParameterRequest>(
|
||||
availability.size());
|
||||
List<DerivedRequestableData> initResponses = new ArrayList<DerivedRequestableData>(
|
||||
availability.size());
|
||||
|
||||
for (TimeAndSpace ast : availability) {
|
||||
DerivedParameterRequest derivRequest = new DerivedParameterRequest();
|
||||
DerivedRequestableData newRecord = new DerivedRequestableData(
|
||||
derivRequest);
|
||||
newRecord.setDataTime(time);
|
||||
newRecord.setDataTime(ast.getTime());
|
||||
newRecord.setSpace(ast.getSpace());
|
||||
derivRequest.setParameterAbbreviation(desc.getAbbreviation());
|
||||
derivRequest.setMethod(method.getName());
|
||||
// get data time for this field
|
||||
derivRequest.setBaseTime(time);
|
||||
derivRequest.setBaseTime(ast.getTime());
|
||||
initResponses.add(newRecord);
|
||||
mapOfRequests.put(time, derivRequest);
|
||||
mapOfRequests.put(ast, derivRequest);
|
||||
}
|
||||
|
||||
for (IDerivParamField ifield : method.getFields()) {
|
||||
|
@ -326,64 +332,48 @@ public class DerivedLevelNode extends AbstractDerivedLevelNode {
|
|||
AbstractRequestableData data = fieldStaticData.get(ifield);
|
||||
if (ifield instanceof DerivParamField) {
|
||||
data = checkFieldUnits((DerivParamField) ifield,
|
||||
Arrays.asList(data)).get(0);
|
||||
Arrays.asList(data)).iterator().next();
|
||||
}
|
||||
for (DerivedParameterRequest request : mapOfRequests.values()) {
|
||||
request.addBaseParam(data);
|
||||
}
|
||||
} else if (fields != null && fields.containsKey(ifield)) {
|
||||
DerivParamField field = (DerivParamField) ifield;
|
||||
AbstractRequestableLevelNode fieldNode = fields.get(field);
|
||||
|
||||
Collection<DataTime> availableTimes = myTimeCache.get(field);
|
||||
if (availableTimes == TIME_AGNOSTIC) {
|
||||
List<AbstractRequestableData> responses = fieldNode
|
||||
.getData(property, timeOut, cache);
|
||||
responses = checkFieldUnits(field, responses);
|
||||
for (DerivedParameterRequest request : mapOfRequests
|
||||
.values()) {
|
||||
for (AbstractRequestableData response : responses) {
|
||||
if (response.getDataTime() == null
|
||||
|| response.getDataTime().equals(
|
||||
response.getDataTime())) {
|
||||
request.addBaseParam(response);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
DataTime[] oldEntryTimes = property.getSelectedEntryTime();
|
||||
Map<DataTime, DataTime> matchTimes = timeMatch(
|
||||
mapOfRequests.keySet(), availableTimes, field);
|
||||
Set<DataTime> newEntryTimes = new HashSet<DataTime>(
|
||||
matchTimes.values());
|
||||
property.setSelectedEntryTimes(newEntryTimes
|
||||
.toArray(new DataTime[newEntryTimes.size()]));
|
||||
List<AbstractRequestableData> responses = fieldNode
|
||||
.getData(property, timeOut, cache);
|
||||
property.setSelectedEntryTimes(oldEntryTimes);
|
||||
responses = checkFieldUnits(field, responses);
|
||||
Map<DataTime, AbstractRequestableData> responseMap = new HashMap<DataTime, AbstractRequestableData>();
|
||||
for (AbstractRequestableData record : responses) {
|
||||
responseMap.put(record.getDataTime(), record);
|
||||
}
|
||||
Iterator<Entry<DataTime, DerivedParameterRequest>> it = mapOfRequests
|
||||
.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Entry<DataTime, DerivedParameterRequest> entry = it
|
||||
.next();
|
||||
DataTime requestTime = matchTimes.get(entry.getKey());
|
||||
AbstractRequestableData data = responseMap
|
||||
.get(requestTime);
|
||||
if (data != null) {
|
||||
entry.getValue().addBaseParam(data);
|
||||
} else {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
AbstractRequestableNode fieldNode = fields.get(field);
|
||||
|
||||
Set<TimeAndSpace> fieldAvailability = availCache.get(field);
|
||||
Map<TimeAndSpace, TimeAndSpace> shiftMap = shiftTime(field,
|
||||
fieldAvailability);
|
||||
if (shiftMap != null) {
|
||||
fieldAvailability = shiftMap.keySet();
|
||||
}
|
||||
Map<TimeAndSpace, MatchResult> matchTimes = matcher.match(
|
||||
availability, fieldAvailability);
|
||||
Collection<AbstractRequestableData> responses = dependencyData
|
||||
.get(fieldNode);
|
||||
responses = checkFieldUnits(field, responses);
|
||||
Map<TimeAndSpace, AbstractRequestableData> responseMap = new HashMap<TimeAndSpace, AbstractRequestableData>();
|
||||
for (AbstractRequestableData record : responses) {
|
||||
responseMap.put(record.getTimeAndSpace(), record);
|
||||
}
|
||||
Iterator<Entry<TimeAndSpace, DerivedParameterRequest>> it = mapOfRequests
|
||||
.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Entry<TimeAndSpace, DerivedParameterRequest> entry = it
|
||||
.next();
|
||||
TimeAndSpace requestTime = matchTimes.get(entry.getKey())
|
||||
.get2();
|
||||
if (shiftMap != null) {
|
||||
requestTime = shiftMap.get(requestTime);
|
||||
}
|
||||
AbstractRequestableData data = responseMap.get(requestTime);
|
||||
if (data != null) {
|
||||
entry.getValue().addBaseParam(data);
|
||||
} else {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new VizException("Error processing Derived parameter:"
|
||||
+ desc.getAbbreviation() + ":" + method.getName() + ":"
|
||||
|
@ -391,11 +381,17 @@ public class DerivedLevelNode extends AbstractDerivedLevelNode {
|
|||
}
|
||||
}
|
||||
|
||||
List<AbstractRequestableData> finalResponses = new ArrayList<AbstractRequestableData>();
|
||||
Set<AbstractRequestableData> finalResponses = new HashSet<AbstractRequestableData>();
|
||||
for (DerivedRequestableData record : initResponses) {
|
||||
if (record.getRequest().getBaseParams().size() == method
|
||||
.getFields().size()) {
|
||||
modifyRequest(record);
|
||||
if (record.getLevel().getMasterLevel().getName().equals("BL")
|
||||
&& record.getLevel().getLevelOneValueAsString()
|
||||
.equals("0.0")
|
||||
&& !record.getLevel().getLevelTwoValueAsString()
|
||||
.equals("30.0"))
|
||||
continue;
|
||||
finalResponses.add(record);
|
||||
}
|
||||
|
||||
|
@ -403,61 +399,6 @@ public class DerivedLevelNode extends AbstractDerivedLevelNode {
|
|||
return finalResponses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a set of times to load, and the available times for a field
|
||||
* generate a map from one to the other, taking into account dTime and fTime
|
||||
*
|
||||
* @param timesToLaod
|
||||
* @param availableTimes
|
||||
* @param field
|
||||
* @return
|
||||
*/
|
||||
private Map<DataTime, DataTime> timeMatch(Collection<DataTime> timesToLaod,
|
||||
Collection<DataTime> availableTimes, DerivParamField field) {
|
||||
// First step is to sort the available times by valid time
|
||||
Map<Long, Set<DataTime>> validMap = new HashMap<Long, Set<DataTime>>();
|
||||
for (DataTime time : availableTimes) {
|
||||
Long validTime = time.getMatchValid();
|
||||
Set<DataTime> timeSet = validMap.get(validTime);
|
||||
if (timeSet == null) {
|
||||
timeSet = new HashSet<DataTime>();
|
||||
validMap.put(validTime, timeSet);
|
||||
}
|
||||
timeSet.add(time);
|
||||
}
|
||||
// For each requested time we find the best available time
|
||||
Map<DataTime, DataTime> results = new HashMap<DataTime, DataTime>();
|
||||
int dTimeInSeconds = getDTimeInSeconds(field);
|
||||
|
||||
if (dTimeInSeconds == -1) {
|
||||
return results;
|
||||
}
|
||||
for (DataTime entryTime : timesToLaod) {
|
||||
Long validTime = entryTime.getMatchValid() + dTimeInSeconds * 1000;
|
||||
if (!validMap.containsKey(validTime)) {
|
||||
// This means we have no data for this field at this
|
||||
// time
|
||||
continue;
|
||||
}
|
||||
DataTime latest = null;
|
||||
for (DataTime time : validMap.get(validTime)) {
|
||||
if (time.getMatchRef() == entryTime.getMatchRef()) {
|
||||
// Prefer a matching ref time
|
||||
latest = time;
|
||||
break;
|
||||
} else if (!method.isFtime()
|
||||
&& (latest == null || latest.getMatchRef() < time
|
||||
.getMatchRef())) {
|
||||
latest = time;
|
||||
}
|
||||
}
|
||||
if (latest != null) {
|
||||
results.put(entryTime, latest);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private int getDTimeInSeconds(DerivParamField field) {
|
||||
int dTimeInSeconds = 0;
|
||||
|
||||
|
@ -474,9 +415,9 @@ public class DerivedLevelNode extends AbstractDerivedLevelNode {
|
|||
return dTimeInSeconds;
|
||||
}
|
||||
|
||||
private List<AbstractRequestableData> checkFieldUnits(
|
||||
DerivParamField field, List<AbstractRequestableData> records) {
|
||||
List<AbstractRequestableData> newRecs = new ArrayList<AbstractRequestableData>(
|
||||
private Collection<AbstractRequestableData> checkFieldUnits(
|
||||
DerivParamField field, Collection<AbstractRequestableData> records) {
|
||||
Set<AbstractRequestableData> newRecs = new HashSet<AbstractRequestableData>(
|
||||
records.size());
|
||||
for (AbstractRequestableData record : records) {
|
||||
if (record.getUnit() != null
|
||||
|
@ -492,44 +433,6 @@ public class DerivedLevelNode extends AbstractDerivedLevelNode {
|
|||
return newRecs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the possible data times for a dTime option.
|
||||
*
|
||||
* @param dataTime
|
||||
* The original data time
|
||||
* @param dTimeInSeconds
|
||||
* The dTime offset in seconds
|
||||
* @param dTinSeconds
|
||||
* The intrinsic time spacing of the current model.
|
||||
* @return A list of possible data times.
|
||||
*/
|
||||
private List<DataTime> generatePossibleDataTimes(DataTime dataTime,
|
||||
DerivParamField field) {
|
||||
int dTimeInSeconds = getDTimeInSeconds(field);
|
||||
int sign = 1;
|
||||
if (dTimeInSeconds < 0) {
|
||||
dTimeInSeconds *= -1;
|
||||
sign = -1;
|
||||
}
|
||||
|
||||
int fTimeInSeconds = dataTime.getFcstTime();
|
||||
long vTimeInMillis = dataTime.getValidTime().getTimeInMillis()
|
||||
- (dTimeInSeconds * 1000 * sign);
|
||||
|
||||
List<DataTime> rval = new ArrayList<DataTime>(
|
||||
(dTimeInSeconds * 2 / dt) + 1);
|
||||
|
||||
for (int fInSeconds = fTimeInSeconds - dTimeInSeconds; fInSeconds <= fTimeInSeconds
|
||||
+ dTimeInSeconds; fInSeconds += dt) {
|
||||
if (fInSeconds >= 0) {
|
||||
rval.add(new DataTime(new Date(vTimeInMillis
|
||||
- (fInSeconds * 1000)), fInSeconds));
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
@ -540,7 +443,7 @@ public class DerivedLevelNode extends AbstractDerivedLevelNode {
|
|||
public List<Dependency> getDependencies() {
|
||||
List<Dependency> dependencies = new ArrayList<Dependency>();
|
||||
if (fields != null) {
|
||||
for (Entry<DerivParamField, AbstractRequestableLevelNode> entry : fields
|
||||
for (Entry<DerivParamField, AbstractRequestableNode> entry : fields
|
||||
.entrySet()) {
|
||||
dependencies.add(new Dependency(entry.getValue(),
|
||||
getDTimeInSeconds(entry.getKey())));
|
||||
|
|
|
@ -1,136 +0,0 @@
|
|||
/**
|
||||
* 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.viz.derivparam.tree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.data.AggregateRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
|
||||
/**
|
||||
*
|
||||
* Builds AggregateRecords which contain all forecast times up to the requested
|
||||
* time.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 8, 2010 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ModelRunLevelNode extends AbstractAliasLevelNode {
|
||||
|
||||
public ModelRunLevelNode(ModelRunLevelNode that) {
|
||||
super(that);
|
||||
}
|
||||
|
||||
public ModelRunLevelNode(AbstractRequestableLevelNode sourceNode,
|
||||
DerivParamDesc desc, DerivParamMethod method, String modelName,
|
||||
Level level) {
|
||||
super(sourceNode, desc, method, modelName, level);
|
||||
}
|
||||
|
||||
public List<AbstractRequestableData> getDataInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException {
|
||||
Set<DataTime> allTimes = this.timeQuery(null, false);
|
||||
Set<DataTime> neededTimes = null;
|
||||
DataTime[] requestedTimes = property.getSelectedEntryTime();
|
||||
if (requestedTimes == null) {
|
||||
neededTimes = allTimes;
|
||||
} else {
|
||||
neededTimes = new HashSet<DataTime>();
|
||||
for (DataTime time : allTimes) {
|
||||
for (DataTime rTime : property.getSelectedEntryTime()) {
|
||||
if (rTime.getRefTime().equals(time.getRefTime())
|
||||
&& rTime.getFcstTime() >= time.getFcstTime()) {
|
||||
neededTimes.add(time);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Map<DataTime, List<AbstractRequestableData>> timeBins = new HashMap<DataTime, List<AbstractRequestableData>>();
|
||||
if (requestedTimes == null) {
|
||||
for (DataTime time : allTimes) {
|
||||
timeBins.put(time, new ArrayList<AbstractRequestableData>());
|
||||
}
|
||||
} else {
|
||||
for (DataTime time : requestedTimes) {
|
||||
timeBins.put(time, new ArrayList<AbstractRequestableData>());
|
||||
}
|
||||
}
|
||||
property.setSelectedEntryTimes(neededTimes
|
||||
.toArray(new DataTime[neededTimes.size()]));
|
||||
|
||||
for (AbstractRequestableData record : sourceNode.getData(property,
|
||||
timeOut, cache)) {
|
||||
for (Entry<DataTime, List<AbstractRequestableData>> entry : timeBins
|
||||
.entrySet()) {
|
||||
DataTime keyTime = entry.getKey();
|
||||
DataTime recordTime = record.getDataTime();
|
||||
if (keyTime.getRefTime().getTime() == recordTime.getRefTime()
|
||||
.getTime()
|
||||
&& keyTime.getFcstTime() >= recordTime.getFcstTime()) {
|
||||
entry.getValue().add(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
List<AbstractRequestableData> records = new ArrayList<AbstractRequestableData>();
|
||||
for (Entry<DataTime, List<AbstractRequestableData>> entry : timeBins
|
||||
.entrySet()) {
|
||||
if (!entry.getValue().isEmpty()) {
|
||||
AggregateRequestableData newRecord = new AggregateRequestableData(
|
||||
entry.getValue());
|
||||
newRecord.setDataTime(entry.getKey());
|
||||
modifyRequest(newRecord);
|
||||
records.add(newRecord);
|
||||
}
|
||||
}
|
||||
return records;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelRunLevelNode clone() {
|
||||
return new ModelRunLevelNode(this);
|
||||
}
|
||||
|
||||
}
|
|
@ -20,19 +20,16 @@
|
|||
package com.raytheon.uf.viz.derivparam.tree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequest;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
|
||||
|
@ -54,20 +51,20 @@ import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
|||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class OrLevelNode extends AbstractDerivedLevelNode {
|
||||
public class OrLevelNode extends AbstractDerivedDataNode {
|
||||
|
||||
private List<AbstractRequestableLevelNode> nodes;
|
||||
private List<AbstractRequestableNode> nodes;
|
||||
|
||||
public OrLevelNode(OrLevelNode that) {
|
||||
super(that);
|
||||
if (that.nodes != null) {
|
||||
this.nodes = new ArrayList<AbstractRequestableLevelNode>(that.nodes);
|
||||
this.nodes = new ArrayList<AbstractRequestableNode>(that.nodes);
|
||||
}
|
||||
}
|
||||
|
||||
public OrLevelNode(Level level, DerivParamDesc desc,
|
||||
DerivParamMethod method, String modelName,
|
||||
List<AbstractRequestableLevelNode> nodes) {
|
||||
List<AbstractRequestableNode> nodes) {
|
||||
this(level, desc, method, modelName, nodes, true);
|
||||
}
|
||||
|
||||
|
@ -90,146 +87,49 @@ public class OrLevelNode extends AbstractDerivedLevelNode {
|
|||
*/
|
||||
public OrLevelNode(Level level, DerivParamDesc desc,
|
||||
DerivParamMethod method, String modelName,
|
||||
List<AbstractRequestableLevelNode> nodes, boolean alias) {
|
||||
List<AbstractRequestableNode> nodes, boolean alias) {
|
||||
super(level, desc, method, modelName);
|
||||
if (alias) {
|
||||
this.nodes = new ArrayList<AbstractRequestableLevelNode>(
|
||||
nodes.size());
|
||||
for (AbstractRequestableLevelNode node : nodes) {
|
||||
this.nodes = new ArrayList<AbstractRequestableNode>(nodes.size());
|
||||
for (AbstractRequestableNode node : nodes) {
|
||||
this.nodes.add(new AliasLevelNode(node, desc, method,
|
||||
modelName, level));
|
||||
}
|
||||
} else {
|
||||
this.nodes = new ArrayList<AbstractRequestableLevelNode>(nodes);
|
||||
this.nodes = new ArrayList<AbstractRequestableNode>(nodes);
|
||||
}
|
||||
}
|
||||
|
||||
public void addNodeToOrList(AbstractRequestableLevelNode node) {
|
||||
public void addNodeToOrList(AbstractRequestableNode node) {
|
||||
nodes.add(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<AbstractRequestableData> getDataInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException {
|
||||
Set<DataTime> requestedTimes = null;
|
||||
DataTime[] requestedTimesArr = property.getSelectedEntryTime();
|
||||
if (requestedTimesArr == null) {
|
||||
requestedTimes = this.timeQuery(null, false);
|
||||
} else {
|
||||
requestedTimes = new HashSet<DataTime>(
|
||||
Arrays.asList(requestedTimesArr));
|
||||
public Map<AbstractRequestableNode, Set<TimeAndSpace>> getDataDependency(
|
||||
Set<TimeAndSpace> availability) throws VizException {
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> result = new HashMap<AbstractRequestableNode, Set<TimeAndSpace>>();
|
||||
for (AbstractRequestableNode node : nodes) {
|
||||
result.put(node, availability);
|
||||
}
|
||||
List<AbstractRequestableData> records = new ArrayList<AbstractRequestableData>(
|
||||
requestedTimes.size());
|
||||
for (AbstractRequestableLevelNode node : nodes) {
|
||||
List<AbstractRequestableData> newRecords = node.getData(property,
|
||||
timeOut, cache);
|
||||
for (AbstractRequestableData record : newRecords) {
|
||||
if (record.getDataTime() == null) {
|
||||
requestedTimes.clear();
|
||||
} else {
|
||||
requestedTimes.remove(record.getDataTime());
|
||||
}
|
||||
}
|
||||
records.addAll(newRecords);
|
||||
if (requestedTimes.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
property.setSelectedEntryTimes(requestedTimes
|
||||
.toArray(new DataTime[requestedTimes.size()]));
|
||||
}
|
||||
return records;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<DataTime> timeQueryInternal(TimeQueryRequest originalRequest,
|
||||
boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
public Set<AbstractRequestableData> getData(
|
||||
Set<TimeAndSpace> availability,
|
||||
Map<AbstractRequestableNode, Set<AbstractRequestableData>> dependencyData)
|
||||
throws VizException {
|
||||
Set<DataTime> results = new HashSet<DataTime>();
|
||||
for (AbstractRequestableLevelNode node : nodes) {
|
||||
Set<DataTime> times = node.timeQuery(originalRequest, latestOnly,
|
||||
cache, latestOnlyCache);
|
||||
if (times == AbstractRequestableLevelNode.TIME_AGNOSTIC) {
|
||||
return times;
|
||||
} else {
|
||||
for (DataTime time : times) {
|
||||
boolean good = true;
|
||||
for (DataTime result : results) {
|
||||
if (result.getMatchRef() == time.getMatchRef()
|
||||
&& result.getMatchFcst() == time.getMatchFcst()) {
|
||||
good = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (good) {
|
||||
results.add(time);
|
||||
}
|
||||
Map<TimeAndSpace, AbstractRequestableData> dataMap = new HashMap<TimeAndSpace, AbstractRequestableData>();
|
||||
for (AbstractRequestableNode node : nodes) {
|
||||
Set<AbstractRequestableData> dataSet = dependencyData.get(node);
|
||||
for (AbstractRequestableData data : dataSet) {
|
||||
TimeAndSpace ast = data.getTimeAndSpace();
|
||||
if (!dataMap.containsKey(ast)) {
|
||||
dataMap.put(ast, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTimeAgnostic() {
|
||||
for (AbstractRequestableLevelNode node : nodes) {
|
||||
if (node.isTimeAgnostic()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, RequestConstraint> getRequestConstraintMap() {
|
||||
Map<String, RequestConstraint> rval = null;
|
||||
List<Map<String, RequestConstraint>> list = new ArrayList<Map<String, RequestConstraint>>(
|
||||
nodes.size());
|
||||
|
||||
for (AbstractRequestableLevelNode node : nodes) {
|
||||
Map<String, RequestConstraint> rcMap = node
|
||||
.getRequestConstraintMap();
|
||||
|
||||
if (rcMap == null) {
|
||||
// sub node has no request constraint short circuit and exit now
|
||||
return null;
|
||||
}
|
||||
|
||||
list.add(node.getRequestConstraintMap());
|
||||
}
|
||||
|
||||
list = mergeConstraints(list);
|
||||
if (list.size() == 1) {
|
||||
rval = list.get(0);
|
||||
} else {
|
||||
// not directly combinable until this method is updated to
|
||||
// return a list of rcMaps
|
||||
rval = null;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRequestConstraints() {
|
||||
boolean rval = true;
|
||||
for (AbstractRequestableLevelNode node : nodes) {
|
||||
if (!node.hasRequestConstraints()) {
|
||||
rval = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rval) {
|
||||
// handle the maps not being directly combinable
|
||||
rval = getRequestConstraintMap() != null;
|
||||
}
|
||||
return rval;
|
||||
return new HashSet<AbstractRequestableData>(dataMap.values());
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -240,7 +140,7 @@ public class OrLevelNode extends AbstractDerivedLevelNode {
|
|||
*/
|
||||
public List<Dependency> getDependencies() {
|
||||
List<Dependency> dependencies = new ArrayList<Dependency>(nodes.size());
|
||||
for (AbstractRequestableLevelNode node : nodes) {
|
||||
for (AbstractRequestableNode node : nodes) {
|
||||
dependencies.add(new Dependency(node, 0));
|
||||
}
|
||||
return dependencies;
|
||||
|
@ -286,4 +186,15 @@ public class OrLevelNode extends AbstractDerivedLevelNode {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TimeAndSpace> getAvailability(
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> availability)
|
||||
throws VizException {
|
||||
Set<TimeAndSpace> myAvailability = new HashSet<TimeAndSpace>();
|
||||
for (AbstractRequestableNode node : nodes) {
|
||||
myAvailability.addAll(availability.get(node));
|
||||
}
|
||||
return myAvailability;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,17 +21,15 @@ package com.raytheon.uf.viz.derivparam.tree;
|
|||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequest;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
|
||||
|
@ -57,16 +55,7 @@ import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
|||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class StaticDataLevelNode extends AbstractDerivedLevelNode {
|
||||
|
||||
@Override
|
||||
protected DbQueryRequest getDataQueryInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException {
|
||||
return null;
|
||||
}
|
||||
public class StaticDataLevelNode extends AbstractDerivedDataNode {
|
||||
|
||||
protected static final String TIME_FIELD = "dataTime";
|
||||
|
||||
|
@ -90,29 +79,18 @@ public class StaticDataLevelNode extends AbstractDerivedLevelNode {
|
|||
this.source = source;
|
||||
}
|
||||
|
||||
public List<AbstractRequestableData> getDataInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException {
|
||||
return Arrays.asList(source);
|
||||
@Override
|
||||
public Map<AbstractRequestableNode, Set<TimeAndSpace>> getDataDependency(
|
||||
Set<TimeAndSpace> availability) throws VizException {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<DataTime> timeQueryInternal(TimeQueryRequest originalRequest,
|
||||
boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
public Set<AbstractRequestableData> getData(
|
||||
Set<TimeAndSpace> availability,
|
||||
Map<AbstractRequestableNode, Set<AbstractRequestableData>> dependencyData)
|
||||
throws VizException {
|
||||
return TIME_AGNOSTIC;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TimeQueryRequest getTimeQueryInternal(
|
||||
TimeQueryRequest originalRequest, boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache)
|
||||
throws VizException {
|
||||
return null;
|
||||
return new HashSet<AbstractRequestableData>(Arrays.asList(source));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -120,11 +98,6 @@ public class StaticDataLevelNode extends AbstractDerivedLevelNode {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTimeAgnostic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
@ -176,4 +149,13 @@ public class StaticDataLevelNode extends AbstractDerivedLevelNode {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TimeAndSpace> getAvailability(
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> availability)
|
||||
throws VizException {
|
||||
Set<TimeAndSpace> result = new HashSet<TimeAndSpace>();
|
||||
result.add(source.getTimeAndSpace());
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,16 +24,16 @@ import java.util.HashMap;
|
|||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequest;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.data.AggregateRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpaceMatcher;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpaceMatcher.MatchResult;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
|
||||
|
@ -69,56 +69,42 @@ public class TimeRangeLevelNode extends AbstractAliasLevelNode {
|
|||
this.dt = that.dt;
|
||||
}
|
||||
|
||||
public TimeRangeLevelNode(AbstractRequestableLevelNode sourceNode,
|
||||
public TimeRangeLevelNode(AbstractRequestableNode sourceNode,
|
||||
DerivParamDesc desc, DerivParamMethod method, String modelName,
|
||||
int startTime, int endTime, int dt, Level level) {
|
||||
Integer startTime, int endTime, int dt, Level level) {
|
||||
super(sourceNode, desc, method, modelName, level);
|
||||
this.startTime = startTime;
|
||||
this.endTime = endTime;
|
||||
this.dt = dt;
|
||||
}
|
||||
|
||||
public List<AbstractRequestableData> getDataInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
@Override
|
||||
public Set<AbstractRequestableData> getData(
|
||||
Set<TimeAndSpace> availability,
|
||||
Map<AbstractRequestableNode, Set<AbstractRequestableData>> dependencyData)
|
||||
throws VizException {
|
||||
Set<DataTime> allTime = sourceNode.timeQuery(null, false);
|
||||
Map<DataTime, List<DataTime>> goodTimes = new HashMap<DataTime, List<DataTime>>();
|
||||
Set<DataTime> timesToRequest = new HashSet<DataTime>();
|
||||
for (DataTime time : allTime) {
|
||||
List<DataTime> neededTimes = calculateNeededTimes(time);
|
||||
if (allTime.containsAll(neededTimes)) {
|
||||
goodTimes.put(time, neededTimes);
|
||||
timesToRequest.addAll(neededTimes);
|
||||
}
|
||||
TimeAndSpaceMatcher matcher = new TimeAndSpaceMatcher();
|
||||
matcher.setIgnoreRange(true);
|
||||
Map<TimeAndSpace, AbstractRequestableData> dataMap = new HashMap<TimeAndSpace, AbstractRequestableData>();
|
||||
for (AbstractRequestableData data : dependencyData.get(sourceNode)) {
|
||||
dataMap.put(data.getTimeAndSpace(), data);
|
||||
}
|
||||
Set<AbstractRequestableData> records = new HashSet<AbstractRequestableData>();
|
||||
for (TimeAndSpace ast : availability) {
|
||||
Set<TimeAndSpace> needed = calculateNeededAvailability(ast);
|
||||
Map<TimeAndSpace, MatchResult> matched = matcher.match(needed,
|
||||
dataMap.keySet());
|
||||
if (TimeAndSpaceMatcher.getAll1(matched).containsAll(needed)) {
|
||||
List<AbstractRequestableData> dataList = new ArrayList<AbstractRequestableData>();
|
||||
for (TimeAndSpace dataTime : TimeAndSpaceMatcher
|
||||
.getAll2(matched)) {
|
||||
dataList.add(dataMap.get(dataTime));
|
||||
|
||||
}
|
||||
property.setSelectedEntryTimes(timesToRequest
|
||||
.toArray(new DataTime[timesToRequest.size()]));
|
||||
Map<DataTime, List<AbstractRequestableData>> timeBins = new HashMap<DataTime, List<AbstractRequestableData>>();
|
||||
for (AbstractRequestableData record : sourceNode.getData(property,
|
||||
timeOut, cache)) {
|
||||
for (Entry<DataTime, List<DataTime>> entry : goodTimes.entrySet()) {
|
||||
if (entry.getValue().contains(record.getDataTime())) {
|
||||
List<AbstractRequestableData> records = timeBins.get(entry
|
||||
.getKey());
|
||||
if (records == null) {
|
||||
records = new ArrayList<AbstractRequestableData>(entry
|
||||
.getValue().size());
|
||||
timeBins.put(entry.getKey(), records);
|
||||
}
|
||||
records.add(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
List<AbstractRequestableData> records = new ArrayList<AbstractRequestableData>();
|
||||
for (Entry<DataTime, List<AbstractRequestableData>> entry : timeBins
|
||||
.entrySet()) {
|
||||
if (entry.getValue().size() == goodTimes.get(entry.getKey()).size()) {
|
||||
AggregateRequestableData newRecord = new AggregateRequestableData(
|
||||
entry.getValue());
|
||||
newRecord.setDataTime(entry.getKey());
|
||||
dataList);
|
||||
newRecord.setDataTime(ast.getTime());
|
||||
newRecord.setSpace(ast.getSpace());
|
||||
modifyRequest(newRecord);
|
||||
records.add(newRecord);
|
||||
}
|
||||
|
@ -127,31 +113,60 @@ public class TimeRangeLevelNode extends AbstractAliasLevelNode {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Set<DataTime> timeQueryInternal(TimeQueryRequest originalRequest,
|
||||
boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
public Set<TimeAndSpace> getAvailability(
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> availability)
|
||||
throws VizException {
|
||||
Set<DataTime> allTime = sourceNode.timeQuery(originalRequest, false,
|
||||
cache, latestOnlyCache);
|
||||
Set<DataTime> goodTimes = new HashSet<DataTime>();
|
||||
for (DataTime time : allTime) {
|
||||
if (allTime.containsAll(calculateNeededTimes(time))) {
|
||||
goodTimes.add(time);
|
||||
TimeAndSpaceMatcher matcher = new TimeAndSpaceMatcher();
|
||||
matcher.setIgnoreRange(true);
|
||||
Set<TimeAndSpace> allAvail = availability.get(sourceNode);
|
||||
Set<TimeAndSpace> goodAvail = new HashSet<TimeAndSpace>();
|
||||
for (TimeAndSpace ast : allAvail) {
|
||||
Set<TimeAndSpace> needed = calculateNeededAvailability(ast);
|
||||
Set<TimeAndSpace> matchedNeeded = TimeAndSpaceMatcher
|
||||
.getAll1(matcher.match(needed, allAvail));
|
||||
if (matchedNeeded.containsAll(needed)) {
|
||||
goodAvail.add(ast);
|
||||
}
|
||||
|
||||
}
|
||||
return goodTimes;
|
||||
return goodAvail;
|
||||
}
|
||||
|
||||
private List<DataTime> calculateNeededTimes(DataTime time) {
|
||||
List<DataTime> times = new ArrayList<DataTime>();
|
||||
for (int i = time.getFcstTime() + this.startTime; i <= time
|
||||
.getFcstTime() + this.endTime; i += dt) {
|
||||
times.add(new DataTime(time.getRefTime(), i));
|
||||
@Override
|
||||
public Map<AbstractRequestableNode, Set<TimeAndSpace>> getDataDependency(
|
||||
Set<TimeAndSpace> availability) {
|
||||
TimeAndSpaceMatcher matcher = new TimeAndSpaceMatcher();
|
||||
matcher.setIgnoreRange(true);
|
||||
Set<TimeAndSpace> sourceAvailability = new HashSet<TimeAndSpace>(
|
||||
availability);
|
||||
for (TimeAndSpace ast : availability) {
|
||||
Set<TimeAndSpace> needed = calculateNeededAvailability(ast);
|
||||
Set<TimeAndSpace> matchedAvail = TimeAndSpaceMatcher
|
||||
.getAll1(matcher.match(needed, availability));
|
||||
sourceAvailability.addAll(matchedAvail);
|
||||
|
||||
}
|
||||
return times;
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> result = new HashMap<AbstractRequestableNode, Set<TimeAndSpace>>();
|
||||
result.put(sourceNode, sourceAvailability);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConstant() {
|
||||
return super.isConstant();
|
||||
}
|
||||
|
||||
private Set<TimeAndSpace> calculateNeededAvailability(TimeAndSpace ast) {
|
||||
Set<TimeAndSpace> result = new HashSet<TimeAndSpace>();
|
||||
int start = dt;
|
||||
if (startTime != null) {
|
||||
start = ast.getTime().getFcstTime() + this.startTime;
|
||||
}
|
||||
for (int i = start; i <= ast.getTime().getFcstTime() + this.endTime; i += dt) {
|
||||
DataTime time = new DataTime(ast.getTime().getRefTime(), i);
|
||||
result.add(new TimeAndSpace(time, ast.getSpace()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -30,12 +30,10 @@ import java.util.Map.Entry;
|
|||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequest;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.data.AggregateRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
|
||||
|
@ -63,7 +61,7 @@ import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
|||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class UnionLevelNode extends AbstractDerivedLevelNode {
|
||||
public class UnionLevelNode extends AbstractDerivedDataNode {
|
||||
|
||||
private static final Comparator<AbstractRequestableData> requestComp = new Comparator<AbstractRequestableData>() {
|
||||
|
||||
|
@ -76,21 +74,20 @@ public class UnionLevelNode extends AbstractDerivedLevelNode {
|
|||
|
||||
};
|
||||
|
||||
protected List<AbstractRequestableLevelNode> nodes;
|
||||
protected List<AbstractRequestableNode> nodes;
|
||||
|
||||
public UnionLevelNode(UnionLevelNode that) {
|
||||
super(that);
|
||||
this.nodes = that.nodes;
|
||||
}
|
||||
|
||||
public UnionLevelNode(List<AbstractRequestableLevelNode> nodes,
|
||||
String modelName) {
|
||||
public UnionLevelNode(List<AbstractRequestableNode> nodes, String modelName) {
|
||||
this.nodes = nodes;
|
||||
this.modelName = modelName;
|
||||
}
|
||||
|
||||
public UnionLevelNode(Level level, String modelName,
|
||||
List<AbstractRequestableLevelNode> nodes) {
|
||||
List<AbstractRequestableNode> nodes) {
|
||||
this.setLevel(level);
|
||||
this.nodes = nodes;
|
||||
this.modelName = modelName;
|
||||
|
@ -98,43 +95,54 @@ public class UnionLevelNode extends AbstractDerivedLevelNode {
|
|||
|
||||
public UnionLevelNode(Level level, DerivParamDesc desc,
|
||||
DerivParamMethod method, String modelName,
|
||||
List<AbstractRequestableLevelNode> nodes) {
|
||||
List<AbstractRequestableNode> nodes) {
|
||||
super(level, desc, method, modelName);
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AbstractRequestableData> getDataInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
public Map<AbstractRequestableNode, Set<TimeAndSpace>> getDataDependency(
|
||||
Set<TimeAndSpace> availability) throws VizException {
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> result = new HashMap<AbstractRequestableNode, Set<TimeAndSpace>>();
|
||||
for (AbstractRequestableNode node : nodes) {
|
||||
result.put(node, availability);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AbstractRequestableData> getData(
|
||||
Set<TimeAndSpace> availability,
|
||||
Map<AbstractRequestableNode, Set<AbstractRequestableData>> dependencyData)
|
||||
throws VizException {
|
||||
List<AbstractRequestableData> rawRecords = new ArrayList<AbstractRequestableData>();
|
||||
|
||||
List<AbstractRequestableLevelNode> requests = new ArrayList<AbstractRequestableLevelNode>(
|
||||
List<AbstractRequestableNode> requests = new ArrayList<AbstractRequestableNode>(
|
||||
nodes);
|
||||
for (AbstractRequestableLevelNode request : requests) {
|
||||
rawRecords.addAll(request.getData(property, timeOut, cache));
|
||||
for (AbstractRequestableNode request : requests) {
|
||||
rawRecords.addAll(dependencyData.get(request));
|
||||
}
|
||||
Map<DataTime, List<AbstractRequestableData>> bins = new HashMap<DataTime, List<AbstractRequestableData>>();
|
||||
Map<TimeAndSpace, List<AbstractRequestableData>> bins = new HashMap<TimeAndSpace, List<AbstractRequestableData>>();
|
||||
for (AbstractRequestableData record : rawRecords) {
|
||||
List<AbstractRequestableData> bin = bins.get(record.getDataTime());
|
||||
List<AbstractRequestableData> bin = bins.get(record
|
||||
.getTimeAndSpace());
|
||||
if (bin == null) {
|
||||
bin = new ArrayList<AbstractRequestableData>();
|
||||
bins.put(record.getDataTime(), bin);
|
||||
bins.put(record.getTimeAndSpace(), bin);
|
||||
}
|
||||
bin.add(record);
|
||||
}
|
||||
List<AbstractRequestableData> records = new ArrayList<AbstractRequestableData>(
|
||||
Set<AbstractRequestableData> records = new HashSet<AbstractRequestableData>(
|
||||
bins.size());
|
||||
for (Entry<DataTime, List<AbstractRequestableData>> entry : bins
|
||||
for (Entry<TimeAndSpace, List<AbstractRequestableData>> entry : bins
|
||||
.entrySet()) {
|
||||
if (entry.getValue().size() >= 2) {
|
||||
Collections.sort(entry.getValue(), requestComp);
|
||||
|
||||
AggregateRequestableData newRecord = new AggregateRequestableData(
|
||||
entry.getValue());
|
||||
newRecord.setDataTime(entry.getKey());
|
||||
newRecord.setDataTime(entry.getKey().getTime());
|
||||
newRecord.setSpace(entry.getKey().getSpace());
|
||||
modifyRequest(newRecord);
|
||||
records.add(newRecord);
|
||||
}
|
||||
|
@ -143,49 +151,28 @@ public class UnionLevelNode extends AbstractDerivedLevelNode {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Set<DataTime> timeQueryInternal(TimeQueryRequest originalRequest,
|
||||
boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
public Set<TimeAndSpace> getAvailability(
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> availability)
|
||||
throws VizException {
|
||||
// Any time in results should have at least 2 nodes with that time
|
||||
Set<DataTime> results = TIME_AGNOSTIC;
|
||||
// Any time in single has at least one node available at that time
|
||||
Set<DataTime> single = new HashSet<DataTime>();
|
||||
List<AbstractRequestableLevelNode> requests = new ArrayList<AbstractRequestableLevelNode>(
|
||||
// things in one are available for one level
|
||||
Set<TimeAndSpace> one = new HashSet<TimeAndSpace>();
|
||||
// things in two are available for two levels.
|
||||
Set<TimeAndSpace> two = new HashSet<TimeAndSpace>();
|
||||
|
||||
List<AbstractRequestableNode> requests = new ArrayList<AbstractRequestableNode>(
|
||||
nodes);
|
||||
for (AbstractRequestableLevelNode request : requests) {
|
||||
Set<DataTime> times = request.timeQuery(originalRequest,
|
||||
latestOnly, cache, latestOnlyCache);
|
||||
if (times == TIME_AGNOSTIC) {
|
||||
continue;
|
||||
} else if (results == TIME_AGNOSTIC) {
|
||||
results = new HashSet<DataTime>();
|
||||
single.addAll(times);
|
||||
} else {
|
||||
// We must have at least two resources with times. The first
|
||||
// node with times will add only to single, after that any
|
||||
// time in single will also be added to results
|
||||
results.addAll(times);
|
||||
results.retainAll(single);
|
||||
single.addAll(times);
|
||||
for (AbstractRequestableNode request : requests) {
|
||||
// Do not request just latest only because if two nodes have
|
||||
// different latests than this will return no times
|
||||
for (TimeAndSpace time : availability.get(request)) {
|
||||
if (one.contains(time)) {
|
||||
two.add(time);
|
||||
} else {
|
||||
one.add(time);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTimeAgnostic() {
|
||||
boolean timeAgnostic = true;
|
||||
|
||||
for (AbstractRequestableLevelNode node : nodes) {
|
||||
if (!node.isTimeAgnostic()) {
|
||||
timeAgnostic = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return timeAgnostic;
|
||||
return two;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -197,7 +184,7 @@ public class UnionLevelNode extends AbstractDerivedLevelNode {
|
|||
@Override
|
||||
public List<Dependency> getDependencies() {
|
||||
List<Dependency> dependencies = new ArrayList<Dependency>(nodes.size());
|
||||
for (AbstractRequestableLevelNode node : nodes) {
|
||||
for (AbstractRequestableNode node : nodes) {
|
||||
dependencies.add(new Dependency(node, 0));
|
||||
}
|
||||
return dependencies;
|
||||
|
|
|
@ -66,6 +66,7 @@ public class GridRequestableData extends AbstractRequestableData {
|
|||
this.gridSource = source;
|
||||
this.source = source.getDatasetId();
|
||||
this.dataTime = source.getDataTime();
|
||||
this.space = source.getLocation();
|
||||
this.level = source.getLevel();
|
||||
this.parameter = source.getParameter().getAbbreviation();
|
||||
this.unit = source.getParameter().getUnit();
|
||||
|
|
|
@ -115,8 +115,8 @@ public class ImportRequestableData extends AliasRequestableData {
|
|||
}
|
||||
|
||||
CoverageUtils covUtil = CoverageUtils.getInstance();
|
||||
GridCoverage sourceGrid = covUtil.getCoverage(sourceRecord.getSource());
|
||||
GridCoverage destGrid = covUtil.getCoverage(this.getSource());
|
||||
GridCoverage sourceGrid = (GridCoverage) sourceRecord.getSpace();
|
||||
GridCoverage destGrid = (GridCoverage) getSpace();
|
||||
Interpolation interpolation = Interpolation
|
||||
.getInstance(Interpolation.INTERP_BICUBIC);
|
||||
if (rval instanceof FloatDataRecord) {
|
||||
|
|
|
@ -88,6 +88,7 @@ public class RadarRequestableData extends GridRequestableData {
|
|||
RadarAdapter.getGridSpacing());
|
||||
this.source = "radar";
|
||||
this.dataTime = source.getDataTime();
|
||||
this.space = RadarAdapter.getInstance().getCoverage();
|
||||
try {
|
||||
this.level = LevelFactory.getInstance().getLevel("TILT",
|
||||
source.getPrimaryElevationAngle());
|
||||
|
|
|
@ -35,11 +35,12 @@ import com.raytheon.uf.common.status.UFStatus;
|
|||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.viz.grid.util.CoverageUtils;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.viz.grid.util.SliceUtil;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
* Requestable data object that returns static data for a GridCoverage dx,dy, or
|
||||
* coriolis.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -60,11 +61,14 @@ public class StaticGridRequestableData extends AbstractRequestableData {
|
|||
|
||||
private StaticGridDataType dataType;
|
||||
|
||||
public StaticGridRequestableData(StaticGridDataType dataType, String source) {
|
||||
public StaticGridRequestableData(StaticGridDataType dataType,
|
||||
String source, GridCoverage coverage) {
|
||||
this.dataType = dataType;
|
||||
this.source = source;
|
||||
this.parameter = dataType.toString();
|
||||
this.parameterName = dataType.toString();
|
||||
this.space = coverage;
|
||||
this.dataTime = TimeAndSpace.TIME_AGNOSTIC;
|
||||
if (StaticGridDataType._dt.equals(dataType)) {
|
||||
this.unit = SI.SECOND;
|
||||
} else {
|
||||
|
@ -101,21 +105,25 @@ public class StaticGridRequestableData extends AbstractRequestableData {
|
|||
|
||||
return new Float(dTinSeconds);
|
||||
} else {
|
||||
GridCoverage coverage = CoverageUtils.getInstance().getCoverage(
|
||||
source);
|
||||
StaticGridData data = StaticGridData.getInstance(coverage);
|
||||
|
||||
switch (dataType) {
|
||||
case coriolis:
|
||||
rval = data.getCoriolis();
|
||||
break;
|
||||
case dx:
|
||||
rval = data.getDx();
|
||||
break;
|
||||
case dy:
|
||||
rval = data.getDy();
|
||||
break;
|
||||
if (this.space instanceof GridCoverage) {
|
||||
StaticGridData data = StaticGridData
|
||||
.getInstance((GridCoverage) this.space);
|
||||
switch (dataType) {
|
||||
case coriolis:
|
||||
rval = data.getCoriolis();
|
||||
break;
|
||||
case dx:
|
||||
rval = data.getDx();
|
||||
break;
|
||||
case dy:
|
||||
rval = data.getDy();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("Cannot get static topo for: "
|
||||
+ this.space);
|
||||
}
|
||||
|
||||
}
|
||||
if (arg instanceof Request) {
|
||||
return SliceUtil.slice(rval, (Request) arg);
|
||||
|
|
|
@ -27,13 +27,12 @@ import com.raytheon.uf.common.datastorage.records.FloatDataRecord;
|
|||
import com.raytheon.uf.common.gridcoverage.GridCoverage;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.viz.grid.util.CoverageUtils;
|
||||
import com.raytheon.viz.grid.util.SliceUtil;
|
||||
import com.raytheon.viz.grid.util.TiltUtils;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
* Requestable Data that generated tilt elevation.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -59,18 +58,20 @@ public class TiltRequestableData extends AbstractRequestableData {
|
|||
|
||||
}
|
||||
|
||||
public TiltRequestableData(String modelName, Level tiltAngle) {
|
||||
public TiltRequestableData(String modelName, Level tiltAngle,
|
||||
GridCoverage coverage) {
|
||||
this.source = modelName;
|
||||
this.unit = SI.METER;
|
||||
this.parameter = "TILT";
|
||||
this.parameterName = "TILT";
|
||||
this.level = tiltAngle;
|
||||
this.space = coverage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatDataRecord getDataValue(Object arg) throws VizException {
|
||||
|
||||
GridCoverage coverage = CoverageUtils.getInstance().getCoverage(source);
|
||||
GridCoverage coverage = (GridCoverage) getSpace();
|
||||
FloatDataRecord fdr = null;
|
||||
if (arg instanceof TiltCenterPoint) {
|
||||
Coordinate tiltLoc = ((TiltCenterPoint) arg).latLon;
|
||||
|
|
|
@ -37,11 +37,11 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
|
|||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.topo.TopoQuery;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.viz.grid.util.CoverageUtils;
|
||||
import com.raytheon.viz.grid.util.SliceUtil;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
* requestable data that queries the topo datastore and transforms the data into
|
||||
* the correct coverage.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -82,7 +82,7 @@ public class TopoRequestableData extends AbstractRequestableData {
|
|||
*/
|
||||
@Override
|
||||
public FloatDataRecord getDataValue(Object arg) throws VizException {
|
||||
GridCoverage coverage = CoverageUtils.getInstance().getCoverage(source);
|
||||
GridCoverage coverage = (GridCoverage) this.getSpace();
|
||||
FloatDataRecord rval = topoCache.get(coverage);
|
||||
|
||||
if (rval == null) {
|
||||
|
|
|
@ -19,19 +19,11 @@
|
|||
**/
|
||||
package com.raytheon.viz.grid.inv;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractCubeLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.CubeLevel;
|
||||
import com.raytheon.viz.grid.data.GridRequestableDataFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -63,35 +55,9 @@ public class CubeLevelNode extends AbstractCubeLevelNode {
|
|||
}
|
||||
|
||||
public CubeLevelNode(
|
||||
List<CubeLevel<AbstractRequestableLevelNode, AbstractRequestableLevelNode>> levels,
|
||||
List<CubeLevel<AbstractRequestableNode, AbstractRequestableNode>> levels,
|
||||
String modelName) {
|
||||
super(levels, modelName);
|
||||
}
|
||||
|
||||
protected List<AbstractRequestableData> wrapRawRecord(List<Object> objs)
|
||||
throws VizException {
|
||||
List<AbstractRequestableData> gribResults = new ArrayList<AbstractRequestableData>(
|
||||
objs.size());
|
||||
GridRequestableDataFactory factory = GridRequestableDataFactory
|
||||
.getInstance();
|
||||
for (Object obj : objs) {
|
||||
AbstractRequestableData record = factory
|
||||
.getGridRequestableData((GridRecord) obj);
|
||||
gribResults.add(record);
|
||||
}
|
||||
|
||||
return gribResults;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void filter(
|
||||
Map<String, RequestConstraint> baseRequestConstraints,
|
||||
Map<String, RequestConstraint> requestContraintsToFilter) {
|
||||
for (Entry<String, RequestConstraint> e : baseRequestConstraints
|
||||
.entrySet()) {
|
||||
if (!requestContraintsToFilter.containsKey(e.getKey())) {
|
||||
requestContraintsToFilter.put(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,20 +21,20 @@ package com.raytheon.viz.grid.inv;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.data.AggregateRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractAliasLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -58,41 +58,29 @@ public class GatherLevelNode extends AbstractAliasLevelNode {
|
|||
super(that);
|
||||
}
|
||||
|
||||
public GatherLevelNode(AbstractRequestableLevelNode sourceNode,
|
||||
public GatherLevelNode(AbstractRequestableNode sourceNode,
|
||||
DerivParamDesc desc, DerivParamMethod method, String modelName,
|
||||
Level level) {
|
||||
super(sourceNode, desc, method, modelName, level);
|
||||
}
|
||||
|
||||
public List<AbstractRequestableData> getDataInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
@Override
|
||||
public Set<AbstractRequestableData> getData(
|
||||
Set<TimeAndSpace> availability,
|
||||
Map<AbstractRequestableNode, Set<AbstractRequestableData>> dependencyData)
|
||||
throws VizException {
|
||||
Map<DataTime, List<AbstractRequestableData>> recordMap = new HashMap<DataTime, List<AbstractRequestableData>>();
|
||||
HashMap<String, RequestConstraint> rcMap = property
|
||||
.getEntryQueryParameters(false);
|
||||
for (String pert : GridInventory.getEnsembles(sourceNode)) {
|
||||
rcMap.put(GridInventory.ENSEMBLE_QUERY,
|
||||
new RequestConstraint(pert.toString()));
|
||||
property.setEntryQueryParameters(rcMap, false);
|
||||
cache.clear();
|
||||
for (AbstractRequestableData record : sourceNode.getData(property,
|
||||
timeOut, cache)) {
|
||||
List<AbstractRequestableData> records = recordMap.get(record
|
||||
.getDataTime());
|
||||
if (records == null) {
|
||||
records = new ArrayList<AbstractRequestableData>();
|
||||
recordMap.put(record.getDataTime(), records);
|
||||
}
|
||||
records.add(record);
|
||||
Map<TimeAndSpace, List<AbstractRequestableData>> availMap = new HashMap<TimeAndSpace, List<AbstractRequestableData>>();
|
||||
for (AbstractRequestableData data : dependencyData.get(sourceNode)) {
|
||||
TimeAndSpace ast = data.getTimeAndSpace();
|
||||
List<AbstractRequestableData> avail = availMap.get(ast);
|
||||
if (avail == null) {
|
||||
avail = new ArrayList<AbstractRequestableData>();
|
||||
availMap.put(ast, avail);
|
||||
}
|
||||
avail.add(data);
|
||||
}
|
||||
rcMap.remove(GridInventory.ENSEMBLE_QUERY);
|
||||
property.setEntryQueryParameters(rcMap, false);
|
||||
List<AbstractRequestableData> result = new ArrayList<AbstractRequestableData>(
|
||||
recordMap.size());
|
||||
for (List<AbstractRequestableData> records : recordMap.values()) {
|
||||
Set<AbstractRequestableData> result = new HashSet<AbstractRequestableData>();
|
||||
for (List<AbstractRequestableData> records : availMap.values()) {
|
||||
AggregateRequestableData record = new AggregateRequestableData(
|
||||
records);
|
||||
modifyRequest(record);
|
||||
|
|
|
@ -66,16 +66,14 @@ import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
|||
import com.raytheon.uf.viz.derivparam.library.DerivParamField;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod.MethodType;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode.Dependency;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedDataNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode.Dependency;
|
||||
import com.raytheon.uf.viz.derivparam.tree.CubeLevel;
|
||||
import com.raytheon.uf.viz.derivparam.tree.StaticDataLevelNode;
|
||||
import com.raytheon.uf.viz.points.IPointChangedListener;
|
||||
import com.raytheon.uf.viz.points.PointsDataManager;
|
||||
import com.raytheon.viz.grid.data.ImportRequestableData;
|
||||
import com.raytheon.viz.grid.data.StaticGridRequestableData;
|
||||
import com.raytheon.viz.grid.data.TiltRequestableData;
|
||||
import com.raytheon.viz.grid.util.CoverageUtils;
|
||||
import com.raytheon.viz.grid.util.RadarAdapter;
|
||||
|
||||
|
@ -214,8 +212,10 @@ public class GridInventory extends AbstractInventory implements
|
|||
ensembles = new ArrayList<String>(1);
|
||||
ensembles.add(ensemble);
|
||||
} else if (!ensembles.contains(ensemble)) {
|
||||
ensembles = new ArrayList<String>(ensembles);
|
||||
ensembles.add(ensemble);
|
||||
}
|
||||
gribNode.setEnsembles(ensembles);
|
||||
}
|
||||
if (!modelsWithPerts.contains(model)) {
|
||||
modelsWithPerts.add(model);
|
||||
|
@ -242,15 +242,15 @@ public class GridInventory extends AbstractInventory implements
|
|||
*/
|
||||
public LevelNode getNode(String source, String parameter, Level level) {
|
||||
try {
|
||||
List<AbstractRequestableLevelNode> nodes = walkTree(null,
|
||||
List<AbstractRequestableNode> nodes = walkTree(null,
|
||||
Arrays.asList(source), Arrays.asList(parameter),
|
||||
Arrays.asList(level), true, true, null);
|
||||
if (nodes == null || nodes.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (nodes.get(0) instanceof AbstractDerivedLevelNode) {
|
||||
if (nodes.get(0) instanceof AbstractDerivedDataNode) {
|
||||
try {
|
||||
updater.addNode((AbstractDerivedLevelNode) nodes.get(0));
|
||||
updater.addNode((AbstractDerivedDataNode) nodes.get(0));
|
||||
} catch (VizException e) {
|
||||
statusHandler
|
||||
.handle(Priority.PROBLEM,
|
||||
|
@ -415,8 +415,8 @@ public class GridInventory extends AbstractInventory implements
|
|||
|
||||
public Set<Level> getAvailableLevels(Map<String, RequestConstraint> query) {
|
||||
Set<Level> levels = new HashSet<Level>();
|
||||
List<AbstractRequestableLevelNode> nodes = evaluateRequestConstraints(query);
|
||||
for (AbstractRequestableLevelNode node : nodes) {
|
||||
List<AbstractRequestableNode> nodes = evaluateRequestConstraints(query);
|
||||
for (AbstractRequestableNode node : nodes) {
|
||||
levels.add(node.getLevel());
|
||||
}
|
||||
return levels;
|
||||
|
@ -429,7 +429,7 @@ public class GridInventory extends AbstractInventory implements
|
|||
* @param query
|
||||
* @return
|
||||
*/
|
||||
public List<AbstractRequestableLevelNode> evaluateRequestConstraints(
|
||||
public List<AbstractRequestableNode> evaluateRequestConstraints(
|
||||
Map<String, RequestConstraint> query) {
|
||||
List<String> sourcesToProcess = getSourcesToProcess(query);
|
||||
List<String> paramsToProcess = getParametersToProcess(query);
|
||||
|
@ -437,14 +437,14 @@ public class GridInventory extends AbstractInventory implements
|
|||
if (!levelsToProcess.isEmpty() && !sourcesToProcess.isEmpty()
|
||||
&& !paramsToProcess.isEmpty()) {
|
||||
try {
|
||||
List<AbstractRequestableLevelNode> nodes = walkTree(null,
|
||||
List<AbstractRequestableNode> nodes = walkTree(null,
|
||||
sourcesToProcess, paramsToProcess, levelsToProcess,
|
||||
true, true, null);
|
||||
try {
|
||||
|
||||
for (AbstractRequestableLevelNode node : nodes) {
|
||||
if (node instanceof AbstractDerivedLevelNode) {
|
||||
updater.addNode((AbstractDerivedLevelNode) node);
|
||||
for (AbstractRequestableNode node : nodes) {
|
||||
if (node instanceof AbstractDerivedDataNode) {
|
||||
updater.addNode((AbstractDerivedDataNode) node);
|
||||
}
|
||||
}
|
||||
} catch (VizException e) {
|
||||
|
@ -465,7 +465,7 @@ public class GridInventory extends AbstractInventory implements
|
|||
}
|
||||
}
|
||||
|
||||
return new ArrayList<AbstractRequestableLevelNode>(0);
|
||||
return new ArrayList<AbstractRequestableNode>(0);
|
||||
}
|
||||
|
||||
public List<String> getEnsembles(Map<String, RequestConstraint> query)
|
||||
|
@ -474,7 +474,8 @@ public class GridInventory extends AbstractInventory implements
|
|||
if (nameRC == null) {
|
||||
// Only bother grabbing nodes with perts
|
||||
nameRC = new RequestConstraint(null, ConstraintType.IN);
|
||||
nameRC.setConstraintValueList(modelsWithPerts);
|
||||
nameRC.setConstraintValueList(modelsWithPerts
|
||||
.toArray(new String[0]));
|
||||
query = new HashMap<String, RequestConstraint>(query);
|
||||
query.put(MODEL_NAME_QUERY, nameRC);
|
||||
} else {
|
||||
|
@ -492,14 +493,14 @@ public class GridInventory extends AbstractInventory implements
|
|||
}
|
||||
}
|
||||
Set<String> ensembles = new HashSet<String>();
|
||||
for (AbstractRequestableLevelNode node : evaluateRequestConstraints(query)) {
|
||||
for (AbstractRequestableNode node : evaluateRequestConstraints(query)) {
|
||||
ensembles.addAll(getEnsembles(node));
|
||||
}
|
||||
|
||||
return new ArrayList<String>(ensembles);
|
||||
|
||||
}
|
||||
|
||||
public static List<String> getEnsembles(AbstractRequestableLevelNode node)
|
||||
protected static List<String> getEnsembles(AbstractRequestableNode node)
|
||||
throws VizException {
|
||||
|
||||
if (node instanceof GridRequestableNode) {
|
||||
|
@ -514,17 +515,16 @@ public class GridInventory extends AbstractInventory implements
|
|||
for (Entry<String, RequestConstraint> entry : rcMap.entrySet()) {
|
||||
dbQuery.addConstraint(entry.getKey(), entry.getValue());
|
||||
}
|
||||
List<Object[]> results = dbQuery.performQuery();
|
||||
List<String> ensembles = new ArrayList<String>(results.size());
|
||||
for (Object[] ensemble : results) {
|
||||
List<String> ensembles = new ArrayList<String>();
|
||||
for (Object[] ensemble : dbQuery.performQuery()) {
|
||||
ensembles.add((String) ensemble[0]);
|
||||
}
|
||||
gNode.setEnsembles(ensembles);
|
||||
return ensembles;
|
||||
} else if (node instanceof GatherLevelNode) {
|
||||
return Collections.emptyList();
|
||||
} else if (node instanceof AbstractDerivedLevelNode) {
|
||||
AbstractDerivedLevelNode dataNode = (AbstractDerivedLevelNode) node;
|
||||
} else if (node instanceof AbstractDerivedDataNode) {
|
||||
AbstractDerivedDataNode dataNode = (AbstractDerivedDataNode) node;
|
||||
Set<String> ensembles = new HashSet<String>();
|
||||
|
||||
for (Dependency dep : dataNode.getDependencies()) {
|
||||
|
@ -626,7 +626,7 @@ public class GridInventory extends AbstractInventory implements
|
|||
}
|
||||
|
||||
@Override
|
||||
protected AbstractDerivedLevelNode getImportNode(
|
||||
protected AbstractDerivedDataNode getImportNode(
|
||||
AbstractRequestableData nodeToImport, SourceNode destSourceNode,
|
||||
DerivParamDesc desc, DerivParamMethod method, Level level) {
|
||||
AbstractRequestableData data = new ImportRequestableData(nodeToImport,
|
||||
|
@ -641,8 +641,8 @@ public class GridInventory extends AbstractInventory implements
|
|||
}
|
||||
|
||||
@Override
|
||||
protected AbstractDerivedLevelNode getImportNode(
|
||||
AbstractRequestableLevelNode nodeToImport,
|
||||
protected AbstractDerivedDataNode getImportNode(
|
||||
AbstractRequestableNode nodeToImport,
|
||||
String nodeToImportSourceName, SourceNode destSourceNode,
|
||||
DerivParamDesc desc, DerivParamMethod method, Level level) {
|
||||
return new ImportLevelNode(nodeToImport, nodeToImportSourceName, desc,
|
||||
|
@ -676,18 +676,18 @@ public class GridInventory extends AbstractInventory implements
|
|||
|
||||
NavigableSet<Level> levels = LevelUtilities
|
||||
.getOrderedSetOfStandardLevels(masterLevelName);
|
||||
List<CubeLevel<AbstractRequestableLevelNode, AbstractRequestableLevelNode>> cubeLevels = new ArrayList<CubeLevel<AbstractRequestableLevelNode, AbstractRequestableLevelNode>>(
|
||||
List<CubeLevel<AbstractRequestableNode, AbstractRequestableNode>> cubeLevels = new ArrayList<CubeLevel<AbstractRequestableNode, AbstractRequestableNode>>(
|
||||
levels.size());
|
||||
|
||||
for (Level fieldLevel : levels) {
|
||||
AbstractRequestableLevelNode pressure = resolveNode(sNode, "P",
|
||||
AbstractRequestableNode pressure = resolveNode(sNode, "P",
|
||||
fieldLevel, stack, nodata);
|
||||
if (pressure != null) {
|
||||
AbstractRequestableLevelNode param = resolveNode(sNode,
|
||||
AbstractRequestableNode param = resolveNode(sNode,
|
||||
field.getParam(), fieldLevel, stack, nodata);
|
||||
|
||||
if (param != null) {
|
||||
CubeLevel<AbstractRequestableLevelNode, AbstractRequestableLevelNode> cl = new CubeLevel<AbstractRequestableLevelNode, AbstractRequestableLevelNode>(
|
||||
CubeLevel<AbstractRequestableNode, AbstractRequestableNode> cl = new CubeLevel<AbstractRequestableNode, AbstractRequestableNode>(
|
||||
pressure, param);
|
||||
cubeLevels.add(cl);
|
||||
}
|
||||
|
@ -716,27 +716,26 @@ public class GridInventory extends AbstractInventory implements
|
|||
DerivParamField field, Level level) {
|
||||
String fieldParamAbbrev = field.getParam();
|
||||
if (StaticGridDataType.getStringValues().contains(fieldParamAbbrev)) {
|
||||
StaticGridDataType staticGridDataType = StaticGridDataType
|
||||
.valueOf(fieldParamAbbrev);
|
||||
return new StaticGridRequestableData(staticGridDataType,
|
||||
sNode.getValue());
|
||||
return new StaticGridDataLevelNode(sNode.getValue(),
|
||||
fieldParamAbbrev);
|
||||
}
|
||||
// Check to see if we can set the field from the
|
||||
// masterlevel name
|
||||
if (level.getMasterLevel().getName().equals(fieldParamAbbrev)) {
|
||||
if ("TILT".equals(fieldParamAbbrev)) {
|
||||
return new TiltRequestableData(sNode.getValue(), level);
|
||||
return new StaticGridDataLevelNode(sNode.getValue(),
|
||||
fieldParamAbbrev, level);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected AbstractDerivedLevelNode createDerivedNode(DerivParamDesc desc,
|
||||
protected AbstractDerivedDataNode createDerivedNode(DerivParamDesc desc,
|
||||
DerivParamMethod method, Level level, List<Object> fields,
|
||||
SourceNode source) {
|
||||
if (method.getMethodType() == MethodType.OTHER
|
||||
&& method.getName().equalsIgnoreCase("Gather")) {
|
||||
AbstractRequestableLevelNode lNode = (AbstractRequestableLevelNode) fields
|
||||
AbstractRequestableNode lNode = (AbstractRequestableNode) fields
|
||||
.get(0);
|
||||
|
||||
try {
|
||||
|
@ -764,5 +763,4 @@ public class GridInventory extends AbstractInventory implements
|
|||
public void pointChanged() {
|
||||
reinitTree();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
/**
|
||||
* 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.viz.grid.inv;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequestSet;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.dataquery.responses.DbQueryResponse;
|
||||
import com.raytheon.uf.common.dataquery.responses.DbQueryResponseSet;
|
||||
import com.raytheon.uf.viz.core.RecordFactory;
|
||||
import com.raytheon.uf.viz.core.datastructure.DecisionTree;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.MetadataContainer;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode;
|
||||
import com.raytheon.viz.grid.data.GridRequestableData;
|
||||
import com.raytheon.viz.grid.data.GridRequestableDataFactory;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* May 10, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class GridMetadataContainer extends MetadataContainer {
|
||||
|
||||
/**
|
||||
* @param originalConstraints
|
||||
*/
|
||||
public GridMetadataContainer(
|
||||
Map<String, RequestConstraint> originalConstraints) {
|
||||
super(originalConstraints);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processRequests() throws VizException {
|
||||
DecisionTree<GridRequestableNode> tree = new DecisionTree<GridRequestableNode>();
|
||||
List<Map<String, RequestConstraint>> constraintMaps = new ArrayList<Map<String, RequestConstraint>>();
|
||||
for (AbstractRequestableNode node : availCache.keySet()) {
|
||||
if (dataCache.containsKey(node)) {
|
||||
continue;
|
||||
}
|
||||
if (node instanceof GridRequestableNode) {
|
||||
GridRequestableNode dataNode = (GridRequestableNode) node;
|
||||
DbQueryRequest request = dataNode.getDataRequest(
|
||||
originalConstraints, availCache.get(node));
|
||||
Map<String, RequestConstraint> constraints = request
|
||||
.getConstraints();
|
||||
tree.insertCriteria(constraints, dataNode, false);
|
||||
constraintMaps.add(constraints);
|
||||
}
|
||||
}
|
||||
if (constraintMaps.isEmpty()) {
|
||||
super.processRequests();
|
||||
return;
|
||||
} else if (constraintMaps.size() == 1) {
|
||||
super.processRequests();
|
||||
return;
|
||||
}
|
||||
List<DbQueryRequest> requests = new ArrayList<DbQueryRequest>();
|
||||
constraintMaps = mergeConstraints(constraintMaps);
|
||||
for (Map<String, RequestConstraint> constraintMap : constraintMaps) {
|
||||
DbQueryRequest dbRequest = new DbQueryRequest();
|
||||
dbRequest.setEntityClass(GridRecord.class.getName());
|
||||
dbRequest.setConstraints(constraintMap);
|
||||
requests.add(dbRequest);
|
||||
}
|
||||
DbQueryRequestSet requestSet = new DbQueryRequestSet();
|
||||
requestSet.setQueries(requests.toArray(new DbQueryRequest[0]));
|
||||
DbQueryResponseSet responseSet = (DbQueryResponseSet) ThriftClient
|
||||
.sendRequest(requestSet);
|
||||
Map<AbstractRequestableNode, Set<AbstractRequestableData>> dataCache = new HashMap<AbstractRequestableNode, Set<AbstractRequestableData>>();
|
||||
GridRequestableDataFactory grdf = GridRequestableDataFactory
|
||||
.getInstance();
|
||||
tree.rebuildTree();
|
||||
for (DbQueryResponse response : responseSet.getResults()) {
|
||||
for (Map<String, Object> result : response.getResults()) {
|
||||
GridRecord record = (GridRecord) result.get(null);
|
||||
Map<String, Object> recordMap = RecordFactory.getInstance()
|
||||
.loadMapFromUri(record.getDataURI());
|
||||
GridRequestableData data = grdf.getGridRequestableData(record);
|
||||
for (GridRequestableNode node : tree.searchTree(recordMap)) {
|
||||
Set<AbstractRequestableData> set = dataCache.get(node);
|
||||
if (set == null) {
|
||||
set = new HashSet<AbstractRequestableData>();
|
||||
dataCache.put(node, set);
|
||||
}
|
||||
set.add(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.dataCache.putAll(dataCache);
|
||||
super.processRequests();
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the list of constraintMaps and merges the constraint maps that
|
||||
* different by only one key into a new list of constraint maps. EX: 5
|
||||
* RequestConstraint Maps for GFS40 Temp on 5 MB levels will be consolidated
|
||||
* into a single RequestConstraint Map using an IN List for the MB levels.
|
||||
*
|
||||
* @param constraintMaps
|
||||
* @return
|
||||
*/
|
||||
public static List<Map<String, RequestConstraint>> mergeConstraints(
|
||||
List<Map<String, RequestConstraint>> constraintMaps) {
|
||||
List<Map<String, RequestConstraint>> rval = new ArrayList<Map<String, RequestConstraint>>();
|
||||
if (constraintMaps != null && constraintMaps.size() > 0) {
|
||||
List<String> mergeKeyList = new ArrayList<String>();
|
||||
|
||||
for (Map<String, RequestConstraint> constraintMap : constraintMaps) {
|
||||
boolean merged = false;
|
||||
int index = 0;
|
||||
|
||||
MERGE_MAP_LOOP: for (index = 0; index < rval.size(); index++) {
|
||||
Map<String, RequestConstraint> mergeMap = rval.get(index);
|
||||
|
||||
// maps must be of same size
|
||||
if (mergeMap.size() == constraintMap.size()) {
|
||||
String mergeKey = mergeKeyList.get(index);
|
||||
|
||||
if (mergeKey != null) {
|
||||
// determine if it matches map except for uniqueKey
|
||||
for (String key : mergeMap.keySet()) {
|
||||
boolean isUniqueKey = mergeKey.equals(key);
|
||||
boolean constraintEquals = mergeMap.get(key)
|
||||
.equals(constraintMap.get(key));
|
||||
|
||||
if (!constraintEquals && !isUniqueKey) {
|
||||
continue MERGE_MAP_LOOP;
|
||||
}
|
||||
}
|
||||
|
||||
// map differs except for key
|
||||
boolean constraintMerged = mergeMap.get(mergeKey)
|
||||
.merge(constraintMap.get(mergeKey));
|
||||
if (!constraintMerged) {
|
||||
continue MERGE_MAP_LOOP;
|
||||
} else {
|
||||
merged = true;
|
||||
break MERGE_MAP_LOOP;
|
||||
}
|
||||
} else {
|
||||
// current mergeMap has never been merged with,
|
||||
// double check that only one key is different
|
||||
// between maps
|
||||
for (String key : mergeMap.keySet()) {
|
||||
if (!mergeMap.get(key).equals(
|
||||
constraintMap.get(key))) {
|
||||
if (mergeKey == null) {
|
||||
// possible merge key, continue checking
|
||||
// map
|
||||
mergeKey = key;
|
||||
} else {
|
||||
// two merge keys found, go to next
|
||||
// merge map
|
||||
continue MERGE_MAP_LOOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// found mergeKey, add to mergeKeyList. If mergeKey
|
||||
// still being null is only possible of mergeMap and
|
||||
// constraintMap contain the exact same constraints,
|
||||
// consider them merged
|
||||
if (mergeKey == null) {
|
||||
merged = true;
|
||||
break MERGE_MAP_LOOP;
|
||||
}
|
||||
|
||||
boolean constraintMerged = mergeMap.get(mergeKey)
|
||||
.merge(constraintMap.get(mergeKey));
|
||||
if (!constraintMerged) {
|
||||
continue MERGE_MAP_LOOP;
|
||||
} else {
|
||||
merged = true;
|
||||
mergeKeyList.set(index, mergeKey);
|
||||
break MERGE_MAP_LOOP;
|
||||
}
|
||||
|
||||
}
|
||||
} // maps same size check
|
||||
} // MERGE_MAP_LOOP
|
||||
|
||||
if (!merged) {
|
||||
Map<String, RequestConstraint> mergeMap = new HashMap<String, RequestConstraint>();
|
||||
|
||||
// deep copy the map
|
||||
for (Map.Entry<String, RequestConstraint> entry : constraintMap
|
||||
.entrySet()) {
|
||||
mergeMap.put(entry.getKey(), entry.getValue().clone());
|
||||
}
|
||||
|
||||
rval.add(mergeMap);
|
||||
mergeKeyList.add(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
}
|
|
@ -19,9 +19,6 @@
|
|||
**/
|
||||
package com.raytheon.viz.grid.inv;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
@ -34,17 +31,21 @@ import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
|||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType;
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.responses.DbQueryResponse;
|
||||
import com.raytheon.uf.common.derivparam.tree.LevelNode;
|
||||
import com.raytheon.uf.common.geospatial.ISpatialObject;
|
||||
import com.raytheon.uf.common.gridcoverage.GridCoverage;
|
||||
import com.raytheon.uf.common.gridcoverage.lookup.GridCoverageLookup;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.catalog.CatalogQuery;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractBaseDataNode;
|
||||
import com.raytheon.viz.grid.data.GridRequestableDataFactory;
|
||||
import com.raytheon.viz.grid.util.CoverageUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -62,7 +63,7 @@ import com.raytheon.viz.grid.data.GridRequestableDataFactory;
|
|||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class GridRequestableNode extends AbstractRequestableLevelNode {
|
||||
public class GridRequestableNode extends AbstractBaseDataNode {
|
||||
|
||||
protected static final String TIME_FIELD = "dataTime";
|
||||
|
||||
|
@ -101,155 +102,77 @@ public class GridRequestableNode extends AbstractRequestableLevelNode {
|
|||
this.rcMap = rcMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTimeAgnostic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, RequestConstraint> getRequestConstraintMap() {
|
||||
return rcMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRequestConstraints() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<DataTime> timeQueryInternal(TimeQueryRequest originalRequest,
|
||||
boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
public Set<AbstractRequestableData> getData(
|
||||
Map<String, RequestConstraint> orignalConstraints,
|
||||
Set<TimeAndSpace> availability, Object response)
|
||||
throws VizException {
|
||||
Set<DataTime> resultsSet = GridTimeCache.getInstance().getTimes(this);
|
||||
if (resultsSet != null) {
|
||||
return resultsSet;
|
||||
}
|
||||
|
||||
DataTime[] results = CatalogQuery.performTimeQuery(rcMap, latestOnly,
|
||||
null);
|
||||
if (results != null) {
|
||||
resultsSet = new HashSet<DataTime>(Arrays.asList(results));
|
||||
if (!latestOnly) {
|
||||
GridTimeCache.getInstance().setTimes(this, resultsSet);
|
||||
}
|
||||
return resultsSet;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode#
|
||||
* getTimeQueryInternal(boolean, java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
protected TimeQueryRequest getTimeQueryInternal(
|
||||
TimeQueryRequest originalRequest, boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache)
|
||||
throws VizException {
|
||||
Set<DataTime> resultsSet = GridTimeCache.getInstance().getTimes(this);
|
||||
if (resultsSet != null) {
|
||||
return null;
|
||||
}
|
||||
return CatalogQuery.getTimeQuery(rcMap, latestOnly, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processTimeQueryResults(boolean latestOnly,
|
||||
List<DataTime> queryResponse) throws VizException {
|
||||
if (!latestOnly) {
|
||||
Set<DataTime> resultsSet = new HashSet<DataTime>(queryResponse);
|
||||
GridTimeCache.getInstance().setTimes(this, resultsSet);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AbstractRequestableData> getDataInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException {
|
||||
DbQueryRequest dbRequest = getDataQueryInternal(property, timeOut,
|
||||
cache);
|
||||
DbQueryResponse response = (DbQueryResponse) ThriftClient
|
||||
.sendRequest(dbRequest);
|
||||
return processDataQueryResults(response);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode#
|
||||
* getDataQueryInternal(com.raytheon.uf.viz.core.catalog.LayerProperty, int)
|
||||
*/
|
||||
@Override
|
||||
protected DbQueryRequest getDataQueryInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException {
|
||||
Map<String, RequestConstraint> oldQuery = property
|
||||
.getEntryQueryParameters(false);
|
||||
|
||||
Map<String, RequestConstraint> newQuery = new HashMap<String, RequestConstraint>(
|
||||
rcMap);
|
||||
for (Entry<String, RequestConstraint> e : oldQuery.entrySet()) {
|
||||
if (!newQuery.containsKey(e.getKey())) {
|
||||
newQuery.put(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
DbQueryRequest dbRequest = new DbQueryRequest();
|
||||
DataTime[] times = property.getSelectedEntryTime();
|
||||
if (times != null && times.length > 0) {
|
||||
RequestConstraint dtRC = new RequestConstraint();
|
||||
dtRC.setConstraintType(ConstraintType.IN);
|
||||
for (DataTime t : times) {
|
||||
dtRC.addToConstraintValueList(t.toString());
|
||||
}
|
||||
newQuery.put("dataTime", dtRC);
|
||||
}
|
||||
newQuery.put(GridConstants.PLUGIN_NAME, new RequestConstraint(
|
||||
GridConstants.GRID));
|
||||
dbRequest.setConstraints(newQuery);
|
||||
return dbRequest;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode#
|
||||
* processQueryResults
|
||||
* (com.raytheon.uf.common.dataquery.responses.DbQueryResponse)
|
||||
*/
|
||||
@Override
|
||||
protected List<AbstractRequestableData> processDataQueryResults(
|
||||
DbQueryResponse response) throws VizException {
|
||||
List<Map<String, Object>> rows = response.getResults();
|
||||
List<AbstractRequestableData> rval = new ArrayList<AbstractRequestableData>(
|
||||
rows.size());
|
||||
GridRequestableDataFactory factory = GridRequestableDataFactory
|
||||
DbQueryResponse dbresponse = (DbQueryResponse) response;
|
||||
GridRequestableDataFactory grdf = GridRequestableDataFactory
|
||||
.getInstance();
|
||||
for (Map<String, Object> objMap : rows) {
|
||||
rval.add(factory.getGridRequestableData((GridRecord) objMap
|
||||
.get(null)));
|
||||
Set<AbstractRequestableData> ards = new HashSet<AbstractRequestableData>();
|
||||
for (Map<String, Object> result : dbresponse.getResults()) {
|
||||
GridRecord record = (GridRecord) result.get(null);
|
||||
ards.add(grdf.getGridRequestableData(record));
|
||||
}
|
||||
return rval;
|
||||
return ards;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @seecom.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode#
|
||||
* getDependencies()
|
||||
*/
|
||||
@Override
|
||||
public List<Dependency> getDependencies() {
|
||||
return Collections.emptyList();
|
||||
public DbQueryRequest getDataRequest(
|
||||
Map<String, RequestConstraint> orignalConstraints,
|
||||
Set<TimeAndSpace> availability) {
|
||||
boolean timeAgnostic = false;
|
||||
boolean spaceAgnostic = false;
|
||||
Set<DataTime> times = new HashSet<DataTime>();
|
||||
Set<ISpatialObject> spaces = new HashSet<ISpatialObject>();
|
||||
for (TimeAndSpace ast : availability) {
|
||||
if (ast.isTimeAgnostic()) {
|
||||
timeAgnostic = true;
|
||||
} else {
|
||||
times.add(ast.getTime());
|
||||
}
|
||||
if (ast.isSpaceAgnostic()) {
|
||||
spaceAgnostic = true;
|
||||
} else {
|
||||
spaces.add(ast.getSpace());
|
||||
}
|
||||
}
|
||||
DbQueryRequest dbRequest = new DbQueryRequest();
|
||||
dbRequest.setEntityClass(GridRecord.class.getName());
|
||||
dbRequest.setConstraints(new HashMap<String, RequestConstraint>(rcMap));
|
||||
for (Entry<String, RequestConstraint> e : orignalConstraints.entrySet()) {
|
||||
if (!rcMap.containsKey(e.getKey())) {
|
||||
dbRequest.addConstraint(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
if (!timeAgnostic) {
|
||||
RequestConstraint timeRc = new RequestConstraint();
|
||||
timeRc.setConstraintType(ConstraintType.IN);
|
||||
for (DataTime time : times) {
|
||||
timeRc.addToConstraintValueList(time.toString());
|
||||
}
|
||||
dbRequest.addConstraint(TIME_FIELD, timeRc);
|
||||
}
|
||||
if (!spaceAgnostic) {
|
||||
RequestConstraint spaceRc = new RequestConstraint();
|
||||
spaceRc.setConstraintType(ConstraintType.IN);
|
||||
for (ISpatialObject space : spaces) {
|
||||
if (space instanceof GridCoverage) {
|
||||
spaceRc.addToConstraintValueList(Integer
|
||||
.toString(((GridCoverage) space).getId()));
|
||||
} else {
|
||||
// TODO figure out the intersection of my spatial object
|
||||
// with this spatial object.
|
||||
}
|
||||
}
|
||||
dbRequest.addConstraint(GridConstants.LOCATION_ID, spaceRc);
|
||||
}
|
||||
return dbRequest;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -300,4 +223,64 @@ public class GridRequestableNode extends AbstractRequestableLevelNode {
|
|||
this.ensembles = ensembles;
|
||||
}
|
||||
|
||||
private String getSource() {
|
||||
return rcMap.get(GridConstants.DATASET_ID).getConstraintValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DbQueryRequest getAvailabilityRequest() {
|
||||
if (GridTimeCache.getInstance().getTimes(this) != null) {
|
||||
return null;
|
||||
}
|
||||
DbQueryRequest request = new DbQueryRequest();
|
||||
request.setEntityClass(GridRecord.class.getName());
|
||||
request.addRequestField(TIME_FIELD);
|
||||
try {
|
||||
if (CoverageUtils.getInstance().getCoverages(getSource()).size() > 1) {
|
||||
request.addRequestField(GridConstants.LOCATION_ID);
|
||||
}
|
||||
} catch (VizException e) {
|
||||
// not really a problem, just request the location from db.
|
||||
UFStatus.getHandler().handle(Priority.VERBOSE,
|
||||
e.getLocalizedMessage(), e);
|
||||
request.addRequestField(GridConstants.LOCATION_ID);
|
||||
}
|
||||
request.setDistinct(true);
|
||||
request.setConstraints(rcMap);
|
||||
return request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TimeAndSpace> getAvailability(Object response)
|
||||
throws VizException {
|
||||
Set<TimeAndSpace> result = new HashSet<TimeAndSpace>();
|
||||
if (response == null) {
|
||||
result = GridTimeCache.getInstance().getTimes(this);
|
||||
if (result == null) {
|
||||
// Oh No! the cache has been cleared since we made our request.
|
||||
response = ThriftClient.sendRequest(getAvailabilityRequest());
|
||||
return getAvailability(response);
|
||||
}
|
||||
GridTimeCache.getInstance().setTimes(this, result);
|
||||
} else if (response instanceof DbQueryResponse) {
|
||||
DbQueryResponse dbresponse = (DbQueryResponse) response;
|
||||
for (Map<String, Object> map : dbresponse.getResults()) {
|
||||
DataTime time = (DataTime) map.get(TIME_FIELD);
|
||||
GridCoverage coverage = null;
|
||||
if (map.containsKey(GridConstants.LOCATION_ID)) {
|
||||
Number locationId = (Number) map
|
||||
.get(GridConstants.LOCATION_ID);
|
||||
coverage = GridCoverageLookup.getInstance().getCoverage(
|
||||
locationId.intValue());
|
||||
} else {
|
||||
coverage = CoverageUtils.getInstance()
|
||||
.getCoverages(getSource()).iterator().next();
|
||||
}
|
||||
result.add(new TimeAndSpace(time, coverage));
|
||||
}
|
||||
GridTimeCache.getInstance().setTimes(this, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import java.util.Map;
|
|||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
|
||||
/**
|
||||
* Cache times for GridRequestableNode's to avoid multiple trips to edex for the
|
||||
|
@ -67,14 +67,14 @@ public class GridTimeCache {
|
|||
|
||||
private class CacheEntry {
|
||||
|
||||
public CacheEntry(Set<DataTime> times) {
|
||||
public CacheEntry(Set<TimeAndSpace> times) {
|
||||
this.insertTime = System.currentTimeMillis();
|
||||
this.times = times;
|
||||
}
|
||||
|
||||
public long insertTime;
|
||||
|
||||
public Set<DataTime> times;
|
||||
public Set<TimeAndSpace> times;
|
||||
|
||||
}
|
||||
|
||||
|
@ -121,12 +121,12 @@ public class GridTimeCache {
|
|||
};
|
||||
|
||||
public synchronized void setTimes(GridRequestableNode gNode,
|
||||
Set<DataTime> times) {
|
||||
Set<TimeAndSpace> times) {
|
||||
cache.put(new GridMapKey(gNode.getRequestConstraintMap()),
|
||||
new CacheEntry(times));
|
||||
}
|
||||
|
||||
public synchronized Set<DataTime> getTimes(GridRequestableNode gNode) {
|
||||
public synchronized Set<TimeAndSpace> getTimes(GridRequestableNode gNode) {
|
||||
GridMapKey key = new GridMapKey(gNode.getRequestConstraintMap());
|
||||
CacheEntry entry = cache.get(key);
|
||||
if (entry == null) {
|
||||
|
|
|
@ -44,8 +44,8 @@ import com.raytheon.uf.common.time.DataTime;
|
|||
import com.raytheon.uf.viz.core.alerts.AlertMessage;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode.Dependency;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedDataNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode.Dependency;
|
||||
import com.raytheon.uf.viz.derivparam.tree.OrLevelNode;
|
||||
import com.raytheon.viz.alerts.IAlertObserver;
|
||||
import com.raytheon.viz.alerts.observers.ProductAlertObserver;
|
||||
|
@ -73,9 +73,9 @@ public class GridUpdater implements IAlertObserver {
|
|||
private class UpdateValue {
|
||||
public int timeOffset;
|
||||
|
||||
public AbstractDerivedLevelNode node;
|
||||
public AbstractDerivedDataNode node;
|
||||
|
||||
public UpdateValue(Integer timeOffset, AbstractDerivedLevelNode node) {
|
||||
public UpdateValue(Integer timeOffset, AbstractDerivedDataNode node) {
|
||||
this.timeOffset = timeOffset == null ? 0 : timeOffset;
|
||||
this.node = node;
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ public class GridUpdater implements IAlertObserver {
|
|||
ProductAlertObserver.removeObserver(GridInventory.PLUGIN_NAME, this);
|
||||
}
|
||||
|
||||
public synchronized void addNode(AbstractDerivedLevelNode node)
|
||||
public synchronized void addNode(AbstractDerivedDataNode node)
|
||||
throws VizException {
|
||||
List<Dependency> dependencies = node.getDependencies();
|
||||
if (dependencies == null || dependencies.isEmpty()) {
|
||||
|
@ -189,8 +189,8 @@ public class GridUpdater implements IAlertObserver {
|
|||
updateMap.put(updateKey, set);
|
||||
}
|
||||
set.add(new UpdateValue(dependency.timeOffset, node));
|
||||
} else if (dependency.node instanceof AbstractDerivedLevelNode) {
|
||||
AbstractDerivedLevelNode dataNode = (AbstractDerivedLevelNode) dependency.node;
|
||||
} else if (dependency.node instanceof AbstractDerivedDataNode) {
|
||||
AbstractDerivedDataNode dataNode = (AbstractDerivedDataNode) dependency.node;
|
||||
for (Dependency d : dataNode.getDependencies()) {
|
||||
d.timeOffset += dependency.timeOffset;
|
||||
if (!dep.contains(d)) {
|
||||
|
@ -309,14 +309,14 @@ public class GridUpdater implements IAlertObserver {
|
|||
*/
|
||||
public synchronized void refreshNodes() {
|
||||
GridTimeCache.getInstance().flush();
|
||||
Set<AbstractDerivedLevelNode> oldNodes = new HashSet<AbstractDerivedLevelNode>();
|
||||
Set<AbstractDerivedDataNode> oldNodes = new HashSet<AbstractDerivedDataNode>();
|
||||
for (Set<UpdateValue> values : updateMap.values()) {
|
||||
for (UpdateValue value : values) {
|
||||
oldNodes.add(value.node);
|
||||
}
|
||||
}
|
||||
updateMap.clear();
|
||||
for (AbstractDerivedLevelNode node : oldNodes) {
|
||||
for (AbstractDerivedDataNode node : oldNodes) {
|
||||
// Get Node will automatically add this to the updater.
|
||||
inventory.getNode(node.getModelName(), node.getDesc()
|
||||
.getAbbreviation(), node.getLevel());
|
||||
|
|
|
@ -19,10 +19,8 @@
|
|||
**/
|
||||
package com.raytheon.viz.grid.inv;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.Set;
|
||||
|
@ -31,16 +29,17 @@ import java.util.TreeSet;
|
|||
import com.raytheon.uf.common.dataplugin.grid.dataset.DatasetInfo;
|
||||
import com.raytheon.uf.common.dataplugin.grid.dataset.DatasetInfoLookup;
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequest;
|
||||
import com.raytheon.uf.common.gridcoverage.GridCoverage;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractAliasLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode;
|
||||
import com.raytheon.viz.grid.data.ImportRequestableData;
|
||||
import com.raytheon.viz.grid.util.CoverageUtils;
|
||||
import com.raytheon.viz.grid.util.RadarAdapter;
|
||||
|
||||
/**
|
||||
|
@ -71,7 +70,7 @@ public class ImportLevelNode extends AbstractAliasLevelNode {
|
|||
this.sourceNodeModelName = that.sourceNodeModelName;
|
||||
}
|
||||
|
||||
public ImportLevelNode(AbstractRequestableLevelNode sourceNode,
|
||||
public ImportLevelNode(AbstractRequestableNode sourceNode,
|
||||
String sourceNodeModelName, DerivParamDesc desc,
|
||||
DerivParamMethod method, String modelName, Level level) {
|
||||
super(sourceNode, desc, method, modelName, level);
|
||||
|
@ -79,89 +78,86 @@ public class ImportLevelNode extends AbstractAliasLevelNode {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<AbstractRequestableData> getDataInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
public Set<AbstractRequestableData> getData(
|
||||
Set<TimeAndSpace> availability,
|
||||
Map<AbstractRequestableNode, Set<AbstractRequestableData>> dependencyData)
|
||||
throws VizException {
|
||||
// change out the time queries
|
||||
DataTime[] selectedTimes = property.getSelectedEntryTime();
|
||||
int numberOfImages = property.getNumberOfImages();
|
||||
try {
|
||||
Set<DataTime> newSelectedTimes = new HashSet<DataTime>(
|
||||
(int) (selectedTimes.length * 2.5));
|
||||
for (DataTime time : selectedTimes) {
|
||||
DataTime[] timesToAdd = boundingSourceTimes.get(time);
|
||||
Set<AbstractRequestableData> origs = dependencyData.get(sourceNode);
|
||||
Set<AbstractRequestableData> results = new HashSet<AbstractRequestableData>(
|
||||
origs.size());
|
||||
Map<DataTime, AbstractRequestableData> timeMap = new HashMap<DataTime, AbstractRequestableData>(
|
||||
(int) (origs.size() * 1.25) + 1);
|
||||
for (AbstractRequestableData orig : origs) {
|
||||
timeMap.put(orig.getDataTime(), orig);
|
||||
}
|
||||
|
||||
// sanity check
|
||||
if (timesToAdd != null) {
|
||||
for (DataTime t : timesToAdd) {
|
||||
newSelectedTimes.add(t);
|
||||
}
|
||||
// need to build ImportRequestableData by bounding nodes
|
||||
for (TimeAndSpace time : availability) {
|
||||
DataTime[] timesToAdd = boundingSourceTimes.get(time.getTime());
|
||||
if (timesToAdd != null) {
|
||||
AbstractRequestableData beforeData = timeMap.get(timesToAdd[0]);
|
||||
AbstractRequestableData afterData = null;
|
||||
|
||||
if (beforeData == null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
property.setSelectedEntryTimes(newSelectedTimes
|
||||
.toArray(new DataTime[0]));
|
||||
property.setNumberOfImages(Math.max(newSelectedTimes.size(),
|
||||
numberOfImages));
|
||||
|
||||
List<AbstractRequestableData> origs = sourceNode.getData(property,
|
||||
timeOut, cache);
|
||||
List<AbstractRequestableData> results = new ArrayList<AbstractRequestableData>(
|
||||
origs.size());
|
||||
Map<DataTime, AbstractRequestableData> timeMap = new HashMap<DataTime, AbstractRequestableData>(
|
||||
(int) (origs.size() * 1.25) + 1);
|
||||
for (AbstractRequestableData orig : origs) {
|
||||
timeMap.put(orig.getDataTime(), orig);
|
||||
}
|
||||
|
||||
// need to build ImportRequestableData by bounding nodes
|
||||
for (DataTime time : selectedTimes) {
|
||||
DataTime[] timesToAdd = boundingSourceTimes.get(time);
|
||||
if (timesToAdd != null) {
|
||||
AbstractRequestableData beforeData = timeMap
|
||||
.get(timesToAdd[0]);
|
||||
AbstractRequestableData afterData = null;
|
||||
|
||||
if (beforeData == null) {
|
||||
if (timesToAdd.length == 2) {
|
||||
afterData = timeMap.get(timesToAdd[1]);
|
||||
if (afterData == null) {
|
||||
continue;
|
||||
}
|
||||
if (timesToAdd.length == 2) {
|
||||
afterData = timeMap.get(timesToAdd[1]);
|
||||
if (afterData == null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
AbstractRequestableData result = new ImportRequestableData(
|
||||
beforeData, afterData, time);
|
||||
modifyRequest(result);
|
||||
results.add(result);
|
||||
}
|
||||
|
||||
AbstractRequestableData result = new ImportRequestableData(
|
||||
beforeData, afterData, time.getTime());
|
||||
result.setSpace(time.getSpace());
|
||||
modifyRequest(result);
|
||||
results.add(result);
|
||||
}
|
||||
return results;
|
||||
} finally {
|
||||
// make sure to return the selectedEntryTimes to proper value
|
||||
property.setSelectedEntryTimes(selectedTimes);
|
||||
property.setNumberOfImages(numberOfImages);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<DataTime> timeQueryInternal(TimeQueryRequest originalRequest,
|
||||
boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
public Map<AbstractRequestableNode, Set<TimeAndSpace>> getDataDependency(
|
||||
Set<TimeAndSpace> times) {
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> result = new HashMap<AbstractRequestableNode, Set<TimeAndSpace>>();
|
||||
result.put(sourceNode, getSourceAvailability(times));
|
||||
return result;
|
||||
}
|
||||
|
||||
private Set<TimeAndSpace> getSourceAvailability(Set<TimeAndSpace> times) {
|
||||
Set<TimeAndSpace> neededTimes = new HashSet<TimeAndSpace>();
|
||||
for (TimeAndSpace time : times) {
|
||||
if (time.isTimeAgnostic()) {
|
||||
for (DataTime[] dtarr : boundingSourceTimes.values()) {
|
||||
for (DataTime dt : dtarr) {
|
||||
neededTimes.add(new TimeAndSpace(dt));
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
for (DataTime dt : boundingSourceTimes.get(time.getTime())) {
|
||||
neededTimes.add(new TimeAndSpace(dt));
|
||||
}
|
||||
}
|
||||
}
|
||||
return neededTimes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TimeAndSpace> getAvailability(
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> availability)
|
||||
throws VizException {
|
||||
boundingSourceTimes.clear();
|
||||
|
||||
// grab this source and discover all available times ala time agnostic,
|
||||
// then see what is available in the imported source, use time
|
||||
// interpolation to verify what data can be achieved
|
||||
NavigableSet<DataTime> sourceDataTimes = new TreeSet<DataTime>(
|
||||
sourceNode.timeQuery(originalRequest, latestOnly, cache,
|
||||
latestOnlyCache));
|
||||
NavigableSet<DataTime> sourceDataTimes = new TreeSet<DataTime>();
|
||||
for (TimeAndSpace ast : availability.get(sourceNode)) {
|
||||
sourceDataTimes.add(ast.getTime());
|
||||
}
|
||||
DatasetInfo sourceInfo = DatasetInfoLookup.getInstance().getInfo(
|
||||
sourceNodeModelName);
|
||||
long sourceDt = 0;
|
||||
|
@ -197,8 +193,14 @@ public class ImportLevelNode extends AbstractAliasLevelNode {
|
|||
boundingSourceTimes.put(time, new DataTime[] { time });
|
||||
}
|
||||
}
|
||||
|
||||
return boundingSourceTimes.keySet();
|
||||
Set<TimeAndSpace> result = new HashSet<TimeAndSpace>();
|
||||
for (DataTime time : boundingSourceTimes.keySet()) {
|
||||
for (GridCoverage coverage : CoverageUtils.getInstance()
|
||||
.getCoverages(modelName)) {
|
||||
result.add(new TimeAndSpace(time, coverage));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,26 +19,12 @@
|
|||
**/
|
||||
package com.raytheon.viz.grid.inv;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.radar.RadarRecord;
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.dataquery.responses.DbQueryResponse;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamField;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractCubeLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.CubeLevel;
|
||||
import com.raytheon.viz.grid.data.RadarRequestableData;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -65,78 +51,14 @@ import com.raytheon.viz.grid.data.RadarRequestableData;
|
|||
* @version 1.0
|
||||
*/
|
||||
public class RadarCubeLevelNode extends AbstractCubeLevelNode {
|
||||
private String paramAbbrev = null;
|
||||
|
||||
public RadarCubeLevelNode(AbstractCubeLevelNode that) {
|
||||
super(that);
|
||||
}
|
||||
|
||||
public RadarCubeLevelNode(
|
||||
List<CubeLevel<AbstractRequestableLevelNode, AbstractRequestableLevelNode>> levels,
|
||||
List<CubeLevel<AbstractRequestableNode, AbstractRequestableNode>> levels,
|
||||
String modelName, DerivParamField field) {
|
||||
super(levels, modelName);
|
||||
paramAbbrev = field.getParam();
|
||||
}
|
||||
|
||||
protected List<AbstractRequestableData> wrapRawRecord(List<Object> objs)
|
||||
throws VizException {
|
||||
List<AbstractRequestableData> gribResults = new ArrayList<AbstractRequestableData>(
|
||||
objs.size());
|
||||
for (Object obj : objs) {
|
||||
AbstractRequestableData record = new RadarRequestableData(
|
||||
(RadarRecord) obj, paramAbbrev);
|
||||
gribResults.add(record);
|
||||
}
|
||||
return gribResults;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.viz.derivparam.tree.AbstractCubeLevelNode#mergedTimeQuery
|
||||
* (java.util.List, boolean)
|
||||
*/
|
||||
@Override
|
||||
protected Set<DataTime> mergedTimeQuery(
|
||||
List<Map<String, RequestConstraint>> requests, boolean latestOnly)
|
||||
throws VizException {
|
||||
// Make sure we have data on at least two levels
|
||||
Map<DataTime, Double> single = new HashMap<DataTime, Double>();
|
||||
Set<DataTime> results = new HashSet<DataTime>();
|
||||
for (Map<String, RequestConstraint> mergeMap : requests) {
|
||||
DbQueryRequest request = new DbQueryRequest();
|
||||
request.setConstraints(mergeMap);
|
||||
String field = "dataTime";
|
||||
String levelField = "primaryElevationAngle";
|
||||
request.addFields(new String[] { field, levelField });
|
||||
|
||||
DbQueryResponse response = (DbQueryResponse) ThriftClient
|
||||
.sendRequest(request);
|
||||
if (response.getResults() == null) {
|
||||
continue;
|
||||
}
|
||||
for (Map<String, Object> map : response.getResults()) {
|
||||
DataTime time = (DataTime) map.get(field);
|
||||
Double level = (Double) map.get(levelField);
|
||||
if (results.contains(time)) {
|
||||
continue;
|
||||
}
|
||||
if (!single.containsKey(time)) {
|
||||
single.put(time, level);
|
||||
} else if (!level.equals(single.get(time))) {
|
||||
single.remove(time);
|
||||
results.add(time);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void filter(
|
||||
Map<String, RequestConstraint> baseRequestConstraints,
|
||||
Map<String, RequestConstraint> requestContraintsToFilter) {
|
||||
// do nothing, no filtering necessary for radar
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
**/
|
||||
package com.raytheon.viz.grid.inv;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
@ -31,17 +29,16 @@ import com.raytheon.uf.common.dataplugin.radar.RadarRecord;
|
|||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType;
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.responses.DbQueryResponse;
|
||||
import com.raytheon.uf.common.derivparam.tree.LevelNode;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.catalog.CatalogQuery;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractBaseDataNode;
|
||||
import com.raytheon.viz.grid.data.RadarRequestableData;
|
||||
import com.raytheon.viz.grid.util.RadarAdapter;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -59,7 +56,7 @@ import com.raytheon.viz.grid.data.RadarRequestableData;
|
|||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RadarRequestableLevelNode extends AbstractRequestableLevelNode {
|
||||
public class RadarRequestableLevelNode extends AbstractBaseDataNode {
|
||||
|
||||
protected static final String TIME_FIELD = "dataTime";
|
||||
|
||||
|
@ -105,42 +102,32 @@ public class RadarRequestableLevelNode extends AbstractRequestableLevelNode {
|
|||
this.rcMap = rcMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTimeAgnostic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, RequestConstraint> getRequestConstraintMap() {
|
||||
return rcMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRequestConstraints() {
|
||||
return true;
|
||||
public DbQueryRequest getAvailabilityRequest() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<DataTime> timeQueryInternal(TimeQueryRequest originalRequest,
|
||||
boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
public Set<TimeAndSpace> getAvailability(Object response)
|
||||
throws VizException {
|
||||
Set<DataTime> resultsSet = RadarUpdater.getInstance().getTimes(this);
|
||||
Set<TimeAndSpace> resultsSet = RadarUpdater.getInstance()
|
||||
.getTimes(this);
|
||||
if (resultsSet != null) {
|
||||
return resultsSet;
|
||||
}
|
||||
|
||||
DataTime[] results = CatalogQuery.performTimeQuery(rcMap, latestOnly,
|
||||
null);
|
||||
DataTime[] results = CatalogQuery.performTimeQuery(rcMap, false, null);
|
||||
if (results != null) {
|
||||
resultsSet = new HashSet<DataTime>(results.length);
|
||||
resultsSet = new HashSet<TimeAndSpace>(results.length);
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
resultsSet.add(results[i]);
|
||||
}
|
||||
if (!latestOnly) {
|
||||
RadarUpdater.getInstance().setTimes(this, resultsSet);
|
||||
resultsSet.add(new TimeAndSpace(results[i], RadarAdapter
|
||||
.getInstance().getCoverage()));
|
||||
}
|
||||
RadarUpdater.getInstance().setTimes(this, resultsSet);
|
||||
return resultsSet;
|
||||
} else {
|
||||
return null;
|
||||
|
@ -148,69 +135,31 @@ public class RadarRequestableLevelNode extends AbstractRequestableLevelNode {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected TimeQueryRequest getTimeQueryInternal(
|
||||
TimeQueryRequest originalRequest, boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache)
|
||||
throws VizException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AbstractRequestableData> getDataInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException {
|
||||
DbQueryRequest dbRequest = getDataQueryInternal(property, timeOut,
|
||||
cache);
|
||||
DbQueryResponse response = (DbQueryResponse) ThriftClient
|
||||
.sendRequest(dbRequest);
|
||||
return processDataQueryResults(response);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode#
|
||||
* getDataQueryInternal(com.raytheon.uf.viz.core.catalog.LayerProperty, int,
|
||||
* java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
protected DbQueryRequest getDataQueryInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException {
|
||||
public DbQueryRequest getDataRequest(
|
||||
Map<String, RequestConstraint> orignalConstraints,
|
||||
Set<TimeAndSpace> availability) {
|
||||
Map<String, RequestConstraint> newQuery = new HashMap<String, RequestConstraint>(
|
||||
rcMap);
|
||||
DbQueryRequest dbRequest = new DbQueryRequest();
|
||||
DataTime[] times = property.getSelectedEntryTime();
|
||||
if (times != null && times.length > 0) {
|
||||
RequestConstraint dtRC = new RequestConstraint();
|
||||
dtRC.setConstraintType(ConstraintType.IN);
|
||||
for (DataTime t : times) {
|
||||
dtRC.addToConstraintValueList(t.toString());
|
||||
}
|
||||
newQuery.put("dataTime", dtRC);
|
||||
RequestConstraint dtRC = new RequestConstraint();
|
||||
dtRC.setConstraintType(ConstraintType.IN);
|
||||
for (TimeAndSpace ast : availability) {
|
||||
dtRC.addToConstraintValueList(ast.getTime().toString());
|
||||
}
|
||||
newQuery.put("dataTime", dtRC);
|
||||
newQuery.put("pluginName", new RequestConstraint("radar"));
|
||||
dbRequest.setConstraints(newQuery);
|
||||
return dbRequest;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode#
|
||||
* processQueryResults
|
||||
* (com.raytheon.uf.common.dataquery.responses.DbQueryResponse)
|
||||
*/
|
||||
@Override
|
||||
protected List<AbstractRequestableData> processDataQueryResults(
|
||||
DbQueryResponse response) throws VizException {
|
||||
List<Map<String, Object>> rows = response.getResults();
|
||||
List<AbstractRequestableData> rval = new ArrayList<AbstractRequestableData>(
|
||||
public Set<AbstractRequestableData> getData(
|
||||
Map<String, RequestConstraint> orignalConstraints,
|
||||
Set<TimeAndSpace> availability, Object response)
|
||||
throws VizException {
|
||||
List<Map<String, Object>> rows = ((DbQueryResponse) response)
|
||||
.getResults();
|
||||
Set<AbstractRequestableData> rval = new HashSet<AbstractRequestableData>(
|
||||
rows.size());
|
||||
// switch to GribRequestableData and build a grib record from the radar
|
||||
// record... won't work because of the get data call, can't be a
|
||||
|
@ -222,11 +171,6 @@ public class RadarRequestableLevelNode extends AbstractRequestableLevelNode {
|
|||
return rval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Dependency> getDependencies() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public String getParamAbbrev() {
|
||||
return paramAbbrev;
|
||||
}
|
||||
|
|
|
@ -1,22 +1,3 @@
|
|||
/**
|
||||
* 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.viz.grid.inv;
|
||||
|
||||
import java.util.Collection;
|
||||
|
@ -40,6 +21,7 @@ import com.raytheon.uf.common.status.UFStatus;
|
|||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.alerts.AlertMessage;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.viz.alerts.IAlertObserver;
|
||||
import com.raytheon.viz.alerts.observers.ProductAlertObserver;
|
||||
import com.raytheon.viz.grid.util.RadarAdapter;
|
||||
|
@ -129,14 +111,14 @@ public class RadarUpdater implements IAlertObserver {
|
|||
|
||||
private class CacheEntry {
|
||||
|
||||
public CacheEntry(Set<DataTime> times) {
|
||||
public CacheEntry(Set<TimeAndSpace> times) {
|
||||
this.insertTime = System.currentTimeMillis();
|
||||
this.times = times;
|
||||
}
|
||||
|
||||
public long insertTime;
|
||||
|
||||
public Set<DataTime> times;
|
||||
public Set<TimeAndSpace> times;
|
||||
|
||||
}
|
||||
|
||||
|
@ -151,7 +133,9 @@ public class RadarUpdater implements IAlertObserver {
|
|||
}
|
||||
};
|
||||
|
||||
private CacheEntry globalTimes;
|
||||
private Set<DataTime> globalTimes;
|
||||
|
||||
private long globalInsertTime;
|
||||
|
||||
private RadarUpdater() {
|
||||
ProductAlertObserver.addObserver("radar", this);
|
||||
|
@ -237,11 +221,12 @@ public class RadarUpdater implements IAlertObserver {
|
|||
return new CacheKey(productCode, elevationAngle);
|
||||
}
|
||||
|
||||
public void setTimes(RadarRequestableLevelNode rNode, Set<DataTime> times) {
|
||||
public void setTimes(RadarRequestableLevelNode rNode,
|
||||
Set<TimeAndSpace> times) {
|
||||
cache.put(getCacheKey(rNode), new CacheEntry(times));
|
||||
}
|
||||
|
||||
public Set<DataTime> getTimes(RadarRequestableLevelNode rNode) {
|
||||
public Set<TimeAndSpace> getTimes(RadarRequestableLevelNode rNode) {
|
||||
CacheKey cacheKey = getCacheKey(rNode);
|
||||
CacheEntry entry = cache.get(cacheKey);
|
||||
if (entry == null) {
|
||||
|
@ -255,18 +240,19 @@ public class RadarUpdater implements IAlertObserver {
|
|||
}
|
||||
|
||||
public void setGlobalTimes(Set<DataTime> times) {
|
||||
globalTimes = new CacheEntry(times);
|
||||
globalTimes = times;
|
||||
globalInsertTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public Set<DataTime> getGlobalTimes() {
|
||||
if (globalTimes == null) {
|
||||
return null;
|
||||
}
|
||||
if (globalTimes.insertTime + CACHE_TIME < System.currentTimeMillis()) {
|
||||
if (globalInsertTime + CACHE_TIME < System.currentTimeMillis()) {
|
||||
globalTimes = null;
|
||||
return null;
|
||||
}
|
||||
return globalTimes.times;
|
||||
return globalTimes;
|
||||
}
|
||||
|
||||
public void clearCache() {
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
/**
|
||||
* 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.viz.grid.inv;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.grid.util.StaticGridDataType;
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.gridcoverage.GridCoverage;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractBaseDataNode;
|
||||
import com.raytheon.viz.grid.data.StaticGridRequestableData;
|
||||
import com.raytheon.viz.grid.data.TiltRequestableData;
|
||||
import com.raytheon.viz.grid.util.CoverageUtils;
|
||||
|
||||
/**
|
||||
* A LevelNode for static grid data that is either constant or can be calculated
|
||||
* based off the coverage.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 13, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class StaticGridDataLevelNode extends AbstractBaseDataNode {
|
||||
|
||||
private String dataType;
|
||||
|
||||
private String source;
|
||||
|
||||
public StaticGridDataLevelNode(String source, String dataType) {
|
||||
this.source = source;
|
||||
this.dataType = dataType;
|
||||
}
|
||||
|
||||
public StaticGridDataLevelNode(String source, String dataType, Level level) {
|
||||
this(source, dataType);
|
||||
setLevel(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DbQueryRequest getAvailabilityRequest() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TimeAndSpace> getAvailability(Object response)
|
||||
throws VizException {
|
||||
Set<TimeAndSpace> result = new HashSet<TimeAndSpace>();
|
||||
for (GridCoverage coverage : CoverageUtils.getInstance().getCoverages(
|
||||
source)) {
|
||||
result.add(new TimeAndSpace(coverage));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DbQueryRequest getDataRequest(
|
||||
Map<String, RequestConstraint> orignalConstraints,
|
||||
Set<TimeAndSpace> availability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AbstractRequestableData> getData(
|
||||
Map<String, RequestConstraint> orignalConstraints,
|
||||
Set<TimeAndSpace> availability, Object response)
|
||||
throws VizException {
|
||||
Set<AbstractRequestableData> results = new HashSet<AbstractRequestableData>();
|
||||
for (TimeAndSpace ast : availability) {
|
||||
if (ast.getSpace() instanceof GridCoverage) {
|
||||
GridCoverage coverage = (GridCoverage) ast.getSpace();
|
||||
AbstractRequestableData data = createRequestableData(coverage);
|
||||
data.setDataTime(ast.getTime());
|
||||
results.add(data);
|
||||
} else {
|
||||
for (GridCoverage coverage : CoverageUtils.getInstance()
|
||||
.getCoverages(source)) {
|
||||
AbstractRequestableData data = createRequestableData(coverage);
|
||||
data.setDataTime(ast.getTime());
|
||||
results.add(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private AbstractRequestableData createRequestableData(GridCoverage coverage) {
|
||||
if (StaticGridDataType.getStringValues().contains(dataType)) {
|
||||
StaticGridDataType staticGridDataType = StaticGridDataType
|
||||
.valueOf(dataType);
|
||||
return new StaticGridRequestableData(staticGridDataType, source,
|
||||
coverage);
|
||||
} else if ("TILT".equals(dataType)) {
|
||||
return new TiltRequestableData(source, level, coverage);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConstant() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -35,7 +35,6 @@ import com.raytheon.uf.viz.core.exception.VizException;
|
|||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.viz.grid.data.GridRequestableData;
|
||||
import com.raytheon.viz.grid.data.TiltRequestableData.TiltCenterPoint;
|
||||
import com.raytheon.viz.grid.util.CoverageUtils;
|
||||
import com.raytheon.viz.grid.util.TiltRequest;
|
||||
|
||||
/**
|
||||
|
@ -64,13 +63,9 @@ public class RequestableDataRecord extends GridRecord {
|
|||
public RequestableDataRecord(AbstractRequestableData requester)
|
||||
throws VizException {
|
||||
this.requester = requester;
|
||||
GridCoverage coverage = CoverageUtils.getInstance().getCoverage(
|
||||
requester.getSource());
|
||||
if (coverage == null && requester instanceof GridRequestableData) {
|
||||
coverage = ((GridRequestableData) requester).getGridSource()
|
||||
.getLocation();
|
||||
CoverageUtils.getInstance().setCoverage(requester.getSource(),
|
||||
coverage);
|
||||
GridCoverage coverage = null;
|
||||
if (requester.getSpace() instanceof GridCoverage) {
|
||||
coverage = (GridCoverage) requester.getSpace();
|
||||
}
|
||||
setDatasetId(requester.getSource());
|
||||
setLocation(coverage);
|
||||
|
|
|
@ -913,7 +913,14 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
|
|||
}
|
||||
|
||||
protected List<PluginDataObject> getPluginDataObjects(DataTime time) {
|
||||
return new ArrayList<PluginDataObject>(pdoMap.get(time));
|
||||
if (time == null) {
|
||||
return null;
|
||||
}
|
||||
List<PluginDataObject> list = pdoMap.get(time);
|
||||
if (list == null) {
|
||||
return null;
|
||||
}
|
||||
return new ArrayList<PluginDataObject>(list);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -333,14 +333,4 @@ public class CoverageUtils implements IAlertObserver {
|
|||
}
|
||||
}
|
||||
|
||||
// use getCoverages to work with moving grids.
|
||||
@Deprecated
|
||||
public GridCoverage getCoverage(String modelName) throws VizException {
|
||||
Collection<GridCoverage> coverages = getCoverages(modelName);
|
||||
if (coverages == null || coverages.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return coverages.iterator().next();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.io.File;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
@ -46,6 +47,7 @@ import com.raytheon.uf.common.datastorage.records.FloatDataRecord;
|
|||
import com.raytheon.uf.common.datastorage.records.IDataRecord;
|
||||
import com.raytheon.uf.common.geospatial.ISpatialEnabled;
|
||||
import com.raytheon.uf.common.geospatial.ISpatialObject;
|
||||
import com.raytheon.uf.common.gridcoverage.GridCoverage;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
|
@ -57,14 +59,18 @@ import com.raytheon.uf.viz.core.datastructure.VizDataCubeException;
|
|||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractDataCubeAdapter;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.AvailabilityContainer;
|
||||
import com.raytheon.uf.viz.derivparam.inv.MetadataContainer;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivedParameterGenerator;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode;
|
||||
import com.raytheon.viz.grid.data.GridRequestableData;
|
||||
import com.raytheon.viz.grid.inv.GridInventory;
|
||||
import com.raytheon.viz.grid.inv.GridMetadataContainer;
|
||||
import com.raytheon.viz.grid.record.RequestableDataRecord;
|
||||
|
||||
/**
|
||||
* A DataCubeAdapter that handles all access to the grid plugin.
|
||||
* DataCubeAdapter for Grid, the primary role is to link the grid datatype into
|
||||
* derived parameters.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -380,7 +386,7 @@ public class GridDataCubeAdapter extends AbstractDataCubeAdapter {
|
|||
* evaluateRequestConstraints(java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
protected List<AbstractRequestableLevelNode> evaluateRequestConstraints(
|
||||
protected List<AbstractRequestableNode> evaluateRequestConstraints(
|
||||
Map<String, RequestConstraint> constraints) {
|
||||
return gridInventory.evaluateRequestConstraints(constraints);
|
||||
}
|
||||
|
@ -411,7 +417,8 @@ public class GridDataCubeAdapter extends AbstractDataCubeAdapter {
|
|||
List<Object> results = new ArrayList<Object>(requesters.size());
|
||||
for (AbstractRequestableData requester : requesters) {
|
||||
List<RequestableDataRecord> records = new ArrayList<RequestableDataRecord>();
|
||||
if (requester.getDataTime() == null) {
|
||||
if (requester.getDataTime() == null
|
||||
|| requester.getTimeAndSpace().isTimeAgnostic()) {
|
||||
DataTime[] entryTime = property.getSelectedEntryTime();
|
||||
if (entryTime != null && entryTime.length > 0) {
|
||||
List<DataTime> entryTimes = new ArrayList<DataTime>(
|
||||
|
@ -448,6 +455,28 @@ public class GridDataCubeAdapter extends AbstractDataCubeAdapter {
|
|||
RequestableDataRecord rec = new RequestableDataRecord(requester);
|
||||
records.add(rec);
|
||||
}
|
||||
if (requester.getSpace() == null
|
||||
|| requester.getTimeAndSpace().isSpaceAgnostic()) {
|
||||
Collection<GridCoverage> coverages = CoverageUtils
|
||||
.getInstance().getCoverages(requester.getSource());
|
||||
if (coverages != null && !coverages.isEmpty()) {
|
||||
List<RequestableDataRecord> spaceRecords = new ArrayList<RequestableDataRecord>();
|
||||
for (RequestableDataRecord record : records) {
|
||||
for (GridCoverage coverage : coverages) {
|
||||
record = new RequestableDataRecord(record);
|
||||
record.setLocation(coverage);
|
||||
try {
|
||||
record.setDataURI(null);
|
||||
record.constructDataURI();
|
||||
} catch (PluginException e) {
|
||||
throw new VizException(e);
|
||||
}
|
||||
spaceRecords.add(record);
|
||||
}
|
||||
}
|
||||
records = spaceRecords;
|
||||
}
|
||||
}
|
||||
results.addAll(records);
|
||||
}
|
||||
if (property.getEntryQueryParameters(false).containsKey(
|
||||
|
@ -463,4 +492,19 @@ public class GridDataCubeAdapter extends AbstractDataCubeAdapter {
|
|||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MetadataContainer createMetadataContainer(
|
||||
Map<String, RequestConstraint> constraints) {
|
||||
return new GridMetadataContainer(constraints);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AvailabilityContainer createAvailabilityContainer() {
|
||||
// using a grid specific container which is able to merge constraints
|
||||
// will result in faster database queries, however the extra processing
|
||||
// time it takes to route the times to the correct nodes is larger than
|
||||
// the time saved.
|
||||
return super.createAvailabilityContainer();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,20 +20,17 @@
|
|||
package com.raytheon.viz.grid.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.derivparam.tree.LevelNode;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.data.FloatRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.library.IDerivParamField;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode.Dependency;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedDataNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode.Dependency;
|
||||
import com.raytheon.uf.viz.derivparam.tree.DerivedLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.StaticDataLevelNode;
|
||||
import com.raytheon.viz.grid.inv.GridInventory;
|
||||
|
@ -114,12 +111,8 @@ public class GridTreeGrapher {
|
|||
}
|
||||
} else if (node instanceof StaticDataLevelNode) {
|
||||
StaticDataLevelNode cNode = (StaticDataLevelNode) node;
|
||||
AbstractRequestableData staticData = cNode
|
||||
.getData(
|
||||
new LayerProperty(),
|
||||
0,
|
||||
new HashMap<AbstractRequestableLevelNode, List<AbstractRequestableData>>())
|
||||
.get(0);
|
||||
AbstractRequestableData staticData = cNode.getData(null, null)
|
||||
.iterator().next();
|
||||
if (staticData instanceof FloatRequestableData) {
|
||||
String abbr = node.getClass().getSimpleName();
|
||||
if (cNode.getDesc() != null) {
|
||||
|
@ -142,8 +135,8 @@ public class GridTreeGrapher {
|
|||
System.out.println("node" + i + " -> node" + that);
|
||||
}
|
||||
}
|
||||
} else if (node instanceof AbstractDerivedLevelNode) {
|
||||
AbstractDerivedLevelNode cNode = (AbstractDerivedLevelNode) node;
|
||||
} else if (node instanceof AbstractDerivedDataNode) {
|
||||
AbstractDerivedDataNode cNode = (AbstractDerivedDataNode) node;
|
||||
String abbr = node.getClass().getSimpleName();
|
||||
if (cNode.getDesc() != null) {
|
||||
abbr = cNode.getDesc().getAbbreviation();
|
||||
|
|
|
@ -59,7 +59,7 @@ import com.raytheon.uf.viz.core.style.level.Level.LevelType;
|
|||
import com.raytheon.uf.viz.core.style.level.SingleLevel;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.OrLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.StaticDataLevelNode;
|
||||
import com.raytheon.viz.core.drawables.ColorMapParameterFactory;
|
||||
|
@ -271,7 +271,7 @@ public class RadarAdapter {
|
|||
desc,
|
||||
method,
|
||||
RADAR_SOURCE,
|
||||
new ArrayList<AbstractRequestableLevelNode>(
|
||||
new ArrayList<AbstractRequestableNode>(
|
||||
productCodes.size()), false);
|
||||
gridParameterNode.addChildNode(gridLevelNode);
|
||||
}
|
||||
|
@ -326,9 +326,11 @@ public class RadarAdapter {
|
|||
topoParam.setParameterUnit("m");
|
||||
topoParam.setValue("Topo");
|
||||
|
||||
StaticDataLevelNode topoNode = new StaticDataLevelNode(sfc, topo,
|
||||
new TopoRequestableData(modelNameNode.getValue()),
|
||||
TopoRequestableData topoData = new TopoRequestableData(
|
||||
modelNameNode.getValue());
|
||||
topoData.setSpace(getCoverage());
|
||||
StaticDataLevelNode topoNode = new StaticDataLevelNode(sfc, topo,
|
||||
topoData, modelNameNode.getValue());
|
||||
topoNode.setLevel(sfc);
|
||||
topoParam.addChildNode(topoNode);
|
||||
modelNameNode.addChildNode(topoParam);
|
||||
|
|
|
@ -10,8 +10,6 @@ Require-Bundle: org.apache.batik,
|
|||
org.eclipse.ui,
|
||||
org.eclipse.core.runtime,
|
||||
com.raytheon.viz.core,
|
||||
com.raytheon.uf.viz.core,
|
||||
org.geotools,
|
||||
com.raytheon.viz.ui,
|
||||
org.apache.commons.lang,
|
||||
javax.measure,
|
||||
|
@ -28,12 +26,12 @@ Export-Package: com.raytheon.viz.pointdata,
|
|||
com.raytheon.viz.pointdata.util
|
||||
Import-Package: com.raytheon.edex.meteoLib,
|
||||
com.raytheon.uf.common.comm,
|
||||
com.raytheon.uf.common.dataplugin.grid,
|
||||
com.raytheon.uf.common.dataplugin.level,
|
||||
com.raytheon.uf.common.derivparam.tree,
|
||||
com.raytheon.uf.common.message.response,
|
||||
com.raytheon.uf.common.pointdata,
|
||||
com.raytheon.uf.common.pointdata.accumulate,
|
||||
com.raytheon.uf.common.serialization.comm,
|
||||
com.raytheon.uf.viz.derivparam.data,
|
||||
com.raytheon.uf.viz.derivparam.inv,
|
||||
com.raytheon.uf.viz.derivparam.library,
|
||||
|
|
|
@ -49,11 +49,12 @@ import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
|||
import com.raytheon.uf.viz.derivparam.library.DerivParamField;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod.MethodType;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedDataNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
* Abstract implementation of a point data inventory that can be used by
|
||||
* datatypes that have point data but don't adhere fully to the point data api.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -95,7 +96,7 @@ public abstract class AbstractPointDataInventory extends AbstractInventory {
|
|||
}
|
||||
}
|
||||
|
||||
public List<AbstractRequestableLevelNode> getNodes(String source,
|
||||
public List<AbstractRequestableNode> getNodes(String source,
|
||||
List<String> parameters, List<Level> levels) throws VizException {
|
||||
parameters = new ArrayList<String>(parameters);
|
||||
try {
|
||||
|
@ -176,15 +177,15 @@ public abstract class AbstractPointDataInventory extends AbstractInventory {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected AbstractDerivedLevelNode getImportNode(
|
||||
protected AbstractDerivedDataNode getImportNode(
|
||||
AbstractRequestableData nodeToImport, SourceNode destSourceNode,
|
||||
DerivParamDesc desc, DerivParamMethod method, Level level) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractDerivedLevelNode getImportNode(
|
||||
AbstractRequestableLevelNode nodeToImport,
|
||||
protected AbstractDerivedDataNode getImportNode(
|
||||
AbstractRequestableNode nodeToImport,
|
||||
String nodeToImportSourceName, SourceNode destSourceNode,
|
||||
DerivParamDesc desc, DerivParamMethod method, Level level) {
|
||||
return null;
|
||||
|
@ -212,7 +213,7 @@ public abstract class AbstractPointDataInventory extends AbstractInventory {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected AbstractDerivedLevelNode createDerivedNode(DerivParamDesc desc,
|
||||
protected AbstractDerivedDataNode createDerivedNode(DerivParamDesc desc,
|
||||
DerivParamMethod method, Level level, List<Object> fields,
|
||||
SourceNode source) {
|
||||
if (method.getMethodType() == MethodType.OTHER) {
|
||||
|
@ -220,22 +221,23 @@ public abstract class AbstractPointDataInventory extends AbstractInventory {
|
|||
int index = fields.size() - 1;
|
||||
index -= 4; // The last 4 fields in order are time, paramName,
|
||||
// totalTime, time increment
|
||||
AbstractRequestableLevelNode tNode = (AbstractRequestableLevelNode) fields
|
||||
AbstractRequestableNode tNode = (AbstractRequestableNode) fields
|
||||
.get(index + 1);
|
||||
List<AbstractRequestableLevelNode> idNodes = new ArrayList<AbstractRequestableLevelNode>(
|
||||
List<AbstractRequestableNode> idNodes = new ArrayList<AbstractRequestableNode>(
|
||||
index + 1);
|
||||
for (int i = 0; i <= index; i++) {
|
||||
idNodes.add((AbstractRequestableLevelNode) fields.get(i));
|
||||
idNodes.add((AbstractRequestableNode) fields.get(i));
|
||||
}
|
||||
return new PointAccumLevelNode(desc, method, idNodes, tNode);
|
||||
return new PointAccumLevelNode(desc, method, idNodes, tNode,
|
||||
source.getValue());
|
||||
} else if (method.getName().equalsIgnoreCase("HeightOf")) {
|
||||
AbstractRequestableLevelNode latNode = (AbstractRequestableLevelNode) fields
|
||||
AbstractRequestableNode latNode = (AbstractRequestableNode) fields
|
||||
.get(0);
|
||||
AbstractRequestableLevelNode lonNode = (AbstractRequestableLevelNode) fields
|
||||
AbstractRequestableNode lonNode = (AbstractRequestableNode) fields
|
||||
.get(1);
|
||||
AbstractRequestableLevelNode timeNode = null;
|
||||
AbstractRequestableNode timeNode = null;
|
||||
if (fields.size() > 2) {
|
||||
timeNode = (AbstractRequestableLevelNode) fields.get(2);
|
||||
timeNode = (AbstractRequestableNode) fields.get(2);
|
||||
}
|
||||
return new HeightOfLevelNode(level, desc, method, latNode,
|
||||
lonNode, timeNode);
|
||||
|
|
|
@ -20,23 +20,24 @@
|
|||
package com.raytheon.viz.pointdata.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequest;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.AvailabilityContainer;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedDataNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
* Node for the HeightOf point data derived parameter
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -51,13 +52,13 @@ import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
|||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class HeightOfLevelNode extends AbstractDerivedLevelNode {
|
||||
public class HeightOfLevelNode extends AbstractDerivedDataNode {
|
||||
|
||||
private AbstractRequestableLevelNode latNode;
|
||||
private AbstractRequestableNode latNode;
|
||||
|
||||
private AbstractRequestableLevelNode lonNode;
|
||||
private AbstractRequestableNode lonNode;
|
||||
|
||||
private AbstractRequestableLevelNode timeNode;
|
||||
private AbstractRequestableNode timeNode;
|
||||
|
||||
/**
|
||||
* @param desc
|
||||
|
@ -66,40 +67,43 @@ public class HeightOfLevelNode extends AbstractDerivedLevelNode {
|
|||
* @param lonNode
|
||||
*/
|
||||
public HeightOfLevelNode(Level level, DerivParamDesc desc,
|
||||
DerivParamMethod method, AbstractRequestableLevelNode latNode,
|
||||
AbstractRequestableLevelNode lonNode,
|
||||
AbstractRequestableLevelNode timeNode) {
|
||||
DerivParamMethod method, AbstractRequestableNode latNode,
|
||||
AbstractRequestableNode lonNode, AbstractRequestableNode timeNode) {
|
||||
super(level, desc, method, null);
|
||||
this.latNode = latNode;
|
||||
this.lonNode = lonNode;
|
||||
this.timeNode = timeNode;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @seecom.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode#
|
||||
* getDataInternal(com.raytheon.uf.viz.core.catalog.LayerProperty, int,
|
||||
* java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
protected List<AbstractRequestableData> getDataInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
public Map<AbstractRequestableNode, Set<TimeAndSpace>> getDataDependency(
|
||||
Set<TimeAndSpace> availability) throws VizException {
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> result = new HashMap<AbstractRequestableNode, Set<TimeAndSpace>>();
|
||||
result.put(latNode, availability);
|
||||
result.put(lonNode, availability);
|
||||
if (timeNode != null) {
|
||||
result.put(timeNode, availability);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AbstractRequestableData> getData(
|
||||
Set<TimeAndSpace> availability,
|
||||
Map<AbstractRequestableNode, Set<AbstractRequestableData>> dependencyData)
|
||||
throws VizException {
|
||||
AbstractRequestableData latRequest = latNode.getData(property, timeOut,
|
||||
cache).get(0);
|
||||
AbstractRequestableData lonRequest = lonNode.getData(property, timeOut,
|
||||
cache).get(0);
|
||||
AbstractRequestableData latRequest = dependencyData.get(latNode)
|
||||
.iterator().next();
|
||||
AbstractRequestableData lonRequest = dependencyData.get(lonNode)
|
||||
.iterator().next();
|
||||
AbstractRequestableData timeRequest = null;
|
||||
if (timeNode != null) {
|
||||
timeRequest = timeNode.getData(property, timeOut, cache).get(0);
|
||||
timeRequest = dependencyData.get(timeNode).iterator().next();
|
||||
}
|
||||
AbstractRequestableData heightOf = new HeightOfRequestableData(
|
||||
this.getLevel(), this.desc.getAbbreviation(), latRequest,
|
||||
lonRequest, timeRequest);
|
||||
return Arrays.asList(heightOf);
|
||||
return new HashSet<AbstractRequestableData>(Arrays.asList(heightOf));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -119,23 +123,10 @@ public class HeightOfLevelNode extends AbstractDerivedLevelNode {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @seecom.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode#
|
||||
* timeQueryInternal(boolean, java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
protected Set<DataTime> timeQueryInternal(TimeQueryRequest originalRequest,
|
||||
boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
public Set<TimeAndSpace> getAvailability(
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> availability)
|
||||
throws VizException {
|
||||
return TIME_AGNOSTIC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTimeAgnostic() {
|
||||
return true;
|
||||
return AvailabilityContainer.AGNOSTIC_SET;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
|||
|
||||
import com.raytheon.edex.meteoLib.Controller;
|
||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridConstants;
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.datastorage.records.FloatDataRecord;
|
||||
|
@ -48,7 +49,7 @@ import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
|||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
* Determines the height of a point using gridded data if it is available.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -185,16 +186,18 @@ public class HeightOfRequestableData extends AbstractRequestableData {
|
|||
|
||||
private Map<String, RequestConstraint> getConstraints() {
|
||||
Map<String, RequestConstraint> constraints = new HashMap<String, RequestConstraint>();
|
||||
constraints.put("pluginName", new RequestConstraint("grib"));
|
||||
constraints.put("modelInfo.parameterAbbreviation",
|
||||
constraints.put(GridConstants.PLUGIN_NAME, new RequestConstraint(
|
||||
GridConstants.GRID));
|
||||
constraints.put(GridConstants.PARAMETER_ABBREVIATION,
|
||||
new RequestConstraint("GH"));
|
||||
constraints.put("modelInfo.modelName", new RequestConstraint("GFS212"));
|
||||
constraints.put("modelInfo.level.masterLevel.name",
|
||||
new RequestConstraint(level.getMasterLevel().getName()));
|
||||
constraints.put("modelInfo.level.levelonevalue", new RequestConstraint(
|
||||
level.getLevelOneValueAsString().toString()));
|
||||
constraints.put("modelInfo.level.leveltwovalue", new RequestConstraint(
|
||||
Level.getInvalidLevelValueAsString()));
|
||||
constraints.put(GridConstants.DATASET_ID, new RequestConstraint(
|
||||
"GFS212"));
|
||||
constraints.put(GridConstants.MASTER_LEVEL_NAME, new RequestConstraint(
|
||||
level.getMasterLevel().getName()));
|
||||
constraints.put(GridConstants.LEVEL_ONE, new RequestConstraint(level
|
||||
.getLevelOneValueAsString().toString()));
|
||||
constraints.put(GridConstants.LEVEL_TWO,
|
||||
new RequestConstraint(Level.getInvalidLevelValueAsString()));
|
||||
return constraints;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,22 +21,24 @@ package com.raytheon.viz.pointdata.util;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequest;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.AvailabilityContainer;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamDesc;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedDataNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
* A Node representing the Accum derived paramteer method which is used by point
|
||||
* data to generate accumulations over time.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -51,52 +53,61 @@ import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
|||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class PointAccumLevelNode extends AbstractDerivedLevelNode {
|
||||
public class PointAccumLevelNode extends AbstractDerivedDataNode {
|
||||
|
||||
private List<AbstractRequestableLevelNode> idNodes;
|
||||
private List<AbstractRequestableNode> idNodes;
|
||||
|
||||
private AbstractRequestableLevelNode timeNode;
|
||||
private AbstractRequestableNode timeNode;
|
||||
|
||||
private String plugin;
|
||||
|
||||
public PointAccumLevelNode(PointAccumLevelNode that) {
|
||||
super(that);
|
||||
this.idNodes = that.idNodes;
|
||||
this.timeNode = that.timeNode;
|
||||
this.plugin = that.plugin;
|
||||
}
|
||||
|
||||
public PointAccumLevelNode(DerivParamDesc desc, DerivParamMethod method,
|
||||
List<AbstractRequestableLevelNode> idNodes,
|
||||
AbstractRequestableLevelNode timeNode) {
|
||||
List<AbstractRequestableNode> idNodes,
|
||||
AbstractRequestableNode timeNode, String plugin) {
|
||||
super(PointDataInventory.getStationLevel(), desc, method, null);
|
||||
this.idNodes = idNodes;
|
||||
this.timeNode = timeNode;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @seecom.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode#
|
||||
* getDataInternal(com.raytheon.uf.viz.core.catalog.LayerProperty, int,
|
||||
* java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
protected List<AbstractRequestableData> getDataInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
public Map<AbstractRequestableNode, Set<TimeAndSpace>> getDataDependency(
|
||||
Set<TimeAndSpace> availability) throws VizException {
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> rval = new HashMap<AbstractRequestableNode, Set<TimeAndSpace>>();
|
||||
for (AbstractRequestableNode idNode : idNodes) {
|
||||
rval.put(idNode, availability);
|
||||
}
|
||||
rval.put(timeNode, availability);
|
||||
return rval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AbstractRequestableData> getData(
|
||||
Set<TimeAndSpace> availability,
|
||||
Map<AbstractRequestableNode, Set<AbstractRequestableData>> dependencyData)
|
||||
throws VizException {
|
||||
List<AbstractRequestableData> idRequesters = new ArrayList<AbstractRequestableData>(
|
||||
idNodes.size());
|
||||
for (AbstractRequestableLevelNode idNode : idNodes) {
|
||||
idRequesters.add(idNode.getData(property, timeOut, cache).get(0));
|
||||
for (AbstractRequestableNode idNode : idNodes) {
|
||||
AbstractRequestableData idRequester = dependencyData.get(idNode)
|
||||
.iterator().next();
|
||||
idRequesters.add(idRequester);
|
||||
}
|
||||
|
||||
AbstractRequestableData rData = new PointAccumRequestableData(
|
||||
idRequesters,
|
||||
timeNode.getData(property, timeOut, cache).get(0), method,
|
||||
property);
|
||||
idRequesters, dependencyData.get(timeNode).iterator().next(),
|
||||
method, plugin);
|
||||
rData.setParameter(desc.getAbbreviation());
|
||||
rData.setParameterName(desc.getName());
|
||||
rData.setUnit(desc.getUnit());
|
||||
return Arrays.asList(rData);
|
||||
return new HashSet<AbstractRequestableData>(Arrays.asList(rData));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -109,30 +120,17 @@ public class PointAccumLevelNode extends AbstractDerivedLevelNode {
|
|||
public List<Dependency> getDependencies() {
|
||||
List<Dependency> dependencies = new ArrayList<Dependency>();
|
||||
dependencies.add(new Dependency(timeNode, 0));
|
||||
for (AbstractRequestableLevelNode idNode : idNodes) {
|
||||
for (AbstractRequestableNode idNode : idNodes) {
|
||||
dependencies.add(new Dependency(idNode, 0));
|
||||
}
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @seecom.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode#
|
||||
* timeQueryInternal(boolean, java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
protected Set<DataTime> timeQueryInternal(TimeQueryRequest originalRequest,
|
||||
boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
public Set<TimeAndSpace> getAvailability(
|
||||
Map<AbstractRequestableNode, Set<TimeAndSpace>> availability)
|
||||
throws VizException {
|
||||
return TIME_AGNOSTIC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTimeAgnostic() {
|
||||
return true;
|
||||
return AvailabilityContainer.AGNOSTIC_SET;
|
||||
}
|
||||
|
||||
public PointAccumLevelNode clone() {
|
||||
|
|
|
@ -30,7 +30,6 @@ import com.raytheon.uf.common.datastorage.records.IntegerDataRecord;
|
|||
import com.raytheon.uf.common.datastorage.records.LongDataRecord;
|
||||
import com.raytheon.uf.common.datastorage.records.StringDataRecord;
|
||||
import com.raytheon.uf.common.pointdata.accumulate.AccumDataRequestMessage;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
|
@ -39,7 +38,8 @@ import com.raytheon.uf.viz.derivparam.library.DerivParamField;
|
|||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
* Carries out the Accum derived parameter method by sending an accum request to
|
||||
* edex.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -65,12 +65,10 @@ public class PointAccumRequestableData extends AbstractRequestableData {
|
|||
public PointAccumRequestableData(
|
||||
List<AbstractRequestableData> idRequesters,
|
||||
AbstractRequestableData timeRequester, DerivParamMethod method,
|
||||
LayerProperty property) throws VizException {
|
||||
String plugin) throws VizException {
|
||||
this.idRequesters = idRequesters;
|
||||
this.timeRequester = timeRequester;
|
||||
this.request = new AccumDataRequestMessage();
|
||||
String plugin = property.getEntryQueryParameters(false)
|
||||
.get("pluginName").getConstraintValue();
|
||||
int index = method.getFields().size() - 1;
|
||||
int minutes = ((DerivParamConstantField) method.getFields()
|
||||
.get(index--)).getValue().intValue();
|
||||
|
|
|
@ -22,11 +22,8 @@ package com.raytheon.viz.pointdata.util;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||
import com.raytheon.uf.common.dataplugin.level.Level;
|
||||
|
@ -52,17 +49,19 @@ import com.raytheon.uf.viz.core.exception.VizException;
|
|||
import com.raytheon.uf.viz.core.level.LevelMappingFactory;
|
||||
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.AvailabilityContainer;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivedParameterGenerator;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode.Dependency;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode;
|
||||
import com.raytheon.viz.pointdata.PointDataRequest;
|
||||
|
||||
/**
|
||||
* This adapter allows a user to request derived parameters from point data
|
||||
* sets. It is important to note that the parameter names differ between grid
|
||||
* and point datasets so any derived parameter writer will need to provide
|
||||
* execute methods for both data types. An obvious example would be Wind Chill
|
||||
* but would easily apply to other derived parameters.
|
||||
* sets. It is important to note that derived parameters for point data is much
|
||||
* different than grid. The primary difference is that while grid is combining
|
||||
* multiple records that represent different parameters, point data is combining
|
||||
* multiple paramters within a single record. As a result point data does not
|
||||
* use the time and space matching functions of derived parameters since they
|
||||
* are guaranteed to match for all parameters within a record.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -146,51 +145,22 @@ public class PointDataCubeAdapter implements IDataCubeAdapter {
|
|||
|
||||
List<Level> levels = LevelMappingFactory.getInstance()
|
||||
.getLevelMappingForKey(levelKey).getLevels();
|
||||
List<AbstractRequestableLevelNode> nodes = inventory.getNodes(source,
|
||||
List<AbstractRequestableNode> nodes = inventory.getNodes(source,
|
||||
Arrays.asList(parameters), levels);
|
||||
// Now we have the nodes, rig the dependencies
|
||||
List<AbstractRequestableLevelNode> deps = new ArrayList<AbstractRequestableLevelNode>(
|
||||
nodes);
|
||||
Set<PointDataLevelNode> baseNodes = new HashSet<PointDataLevelNode>();
|
||||
Set<String> baseParams = new HashSet<String>();
|
||||
for (int i = 0; i < deps.size(); i++) {
|
||||
AbstractRequestableLevelNode node = deps.get(i);
|
||||
if (node instanceof PointDataLevelNode) {
|
||||
baseNodes.add((PointDataLevelNode) node);
|
||||
baseParams.add(((PointDataLevelNode) node).getParameter());
|
||||
} else {
|
||||
for (Dependency dep : node.getDependencies()) {
|
||||
deps.add(dep.node);
|
||||
}
|
||||
}
|
||||
PointMetadataContainer pmc = new PointMetadataContainer(queryParams,
|
||||
Arrays.asList(parameters), this);
|
||||
for (AbstractRequestableNode node : nodes) {
|
||||
pmc.prepareRequests(node, AvailabilityContainer.AGNOSTIC_SET);
|
||||
}
|
||||
if (Arrays.asList(parameters).contains("dataURI")) {
|
||||
baseParams.add("dataURI");
|
||||
}
|
||||
PointDataContainer pdc = getBaseRecords(baseParams, queryParams);
|
||||
if (pdc == null) {
|
||||
return pdc;
|
||||
}
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache = new HashMap<AbstractRequestableLevelNode, List<AbstractRequestableData>>();
|
||||
for (PointDataLevelNode node : baseNodes) {
|
||||
IDataRecord rec = pdc.getParameterRecord(node.getParameter());
|
||||
cache.put(node, Arrays
|
||||
.asList((AbstractRequestableData) new PointRequestableData(
|
||||
rec, pdc.getDescription(node.getParameter())
|
||||
.getUnitObject())));
|
||||
if (nodes.contains(node)) {
|
||||
nodes.remove(node);
|
||||
} else if (!Arrays.asList("id", "latitude", "longitude", "dataURI")
|
||||
.contains(rec.getName())) {
|
||||
pdc.remove(rec.getName());
|
||||
}
|
||||
}
|
||||
LayerProperty lp = new LayerProperty();
|
||||
lp.setEntryQueryParameters(queryParams, false);
|
||||
List<AbstractRequestableData> requests = new ArrayList<AbstractRequestableData>();
|
||||
for (AbstractRequestableLevelNode node : nodes) {
|
||||
|
||||
requests.addAll(node.getData(lp, 60000, cache));
|
||||
for (AbstractRequestableNode node : nodes) {
|
||||
requests.addAll(pmc.getData(node,
|
||||
AvailabilityContainer.AGNOSTIC_SET));
|
||||
}
|
||||
PointDataContainer pdc = pmc.getContainer();
|
||||
if (pdc == null) {
|
||||
return null;
|
||||
}
|
||||
for (AbstractRequestableData request : requests) {
|
||||
String unit = request.getUnit() == null ? null : request.getUnit()
|
||||
|
@ -253,7 +223,7 @@ public class PointDataCubeAdapter implements IDataCubeAdapter {
|
|||
return type;
|
||||
}
|
||||
|
||||
protected PointDataContainer getBaseRecords(Collection<String> baseParams,
|
||||
public PointDataContainer getBaseRecords(Collection<String> baseParams,
|
||||
Map<String, RequestConstraint> queryParams) throws VizException {
|
||||
String plugin = queryParams.get(PLUGIN_NAME).getConstraintValue();
|
||||
return PointDataRequest.requestPointDataAllLevels(null, plugin,
|
||||
|
|
|
@ -19,24 +19,21 @@
|
|||
**/
|
||||
package com.raytheon.viz.pointdata.util;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.dataquery.requests.TimeQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.responses.DbQueryResponse;
|
||||
import com.raytheon.uf.common.derivparam.tree.LevelNode;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.catalog.LayerProperty;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
||||
import com.raytheon.uf.viz.derivparam.inv.AvailabilityContainer;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractBaseDataNode;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
* A BaseDataNode for PointData types so that they can be used within derived
|
||||
* parameters.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -51,7 +48,7 @@ import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode;
|
|||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class PointDataLevelNode extends AbstractRequestableLevelNode {
|
||||
public class PointDataLevelNode extends AbstractBaseDataNode {
|
||||
|
||||
private String parameter;
|
||||
|
||||
|
@ -72,101 +69,19 @@ public class PointDataLevelNode extends AbstractRequestableLevelNode {
|
|||
return parameter;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @seecom.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode#
|
||||
* getDataInternal(com.raytheon.uf.viz.core.catalog.LayerProperty, int,
|
||||
* java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
protected List<AbstractRequestableData> getDataInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException {
|
||||
return cache.remove(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode#
|
||||
* getDataQueryInternal(com.raytheon.uf.viz.core.catalog.LayerProperty, int,
|
||||
* java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
protected DbQueryRequest getDataQueryInternal(
|
||||
LayerProperty property,
|
||||
int timeOut,
|
||||
Map<AbstractRequestableLevelNode, List<AbstractRequestableData>> cache)
|
||||
throws VizException {
|
||||
throw new UnsupportedOperationException(
|
||||
"PointData nodes do not support returning data query");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode#
|
||||
* processQueryResults
|
||||
* (com.raytheon.uf.common.dataquery.responses.DbQueryResponse)
|
||||
*/
|
||||
@Override
|
||||
protected List<AbstractRequestableData> processDataQueryResults(
|
||||
DbQueryResponse queryResponse) throws VizException {
|
||||
throw new UnsupportedOperationException(
|
||||
"PointData nodes do not support processing data query");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TimeQueryRequest getTimeQueryInternal(
|
||||
TimeQueryRequest originalRequest, boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache)
|
||||
throws VizException {
|
||||
throw new UnsupportedOperationException(
|
||||
"PointData nodes do not support returning time query");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @seecom.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode#
|
||||
* getDependencies()
|
||||
*/
|
||||
@Override
|
||||
public List<Dependency> getDependencies() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @seecom.raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode#
|
||||
* timeQueryInternal(boolean, java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
protected Set<DataTime> timeQueryInternal(TimeQueryRequest originalRequest,
|
||||
boolean latestOnly,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> cache,
|
||||
Map<AbstractRequestableLevelNode, Set<DataTime>> latestOnlyCache)
|
||||
throws VizException {
|
||||
return TIME_AGNOSTIC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTimeAgnostic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, RequestConstraint> getRequestConstraintMap() {
|
||||
public DbQueryRequest getDataRequest(
|
||||
Map<String, RequestConstraint> orignalConstraints,
|
||||
Set<TimeAndSpace> availability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRequestConstraints() {
|
||||
return false;
|
||||
public Set<AbstractRequestableData> getData(
|
||||
Map<String, RequestConstraint> orignalConstraints,
|
||||
Set<TimeAndSpace> availability, Object response)
|
||||
throws VizException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -209,4 +124,15 @@ public class PointDataLevelNode extends AbstractRequestableLevelNode {
|
|||
public PointDataLevelNode clone() {
|
||||
return new PointDataLevelNode(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DbQueryRequest getAvailabilityRequest() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TimeAndSpace> getAvailability(Object response) {
|
||||
return AvailabilityContainer.AGNOSTIC_SET;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
/**
|
||||
* 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.viz.pointdata.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.datastorage.records.IDataRecord;
|
||||
import com.raytheon.uf.common.pointdata.PointDataContainer;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.MetadataContainer;
|
||||
import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode;
|
||||
|
||||
/**
|
||||
* A MetadataContainer that is optimized for point data. This container ensures
|
||||
* that the point data api is used properly to bulk request all the base
|
||||
* parameters at once.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 13, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class PointMetadataContainer extends MetadataContainer {
|
||||
|
||||
private final PointDataCubeAdapter pdca;
|
||||
|
||||
private final List<String> requestedParameters;
|
||||
|
||||
private PointDataContainer pdc;
|
||||
|
||||
public PointMetadataContainer(
|
||||
Map<String, RequestConstraint> originalConstraints,
|
||||
List<String> requestedParameters, PointDataCubeAdapter pdca) {
|
||||
super(originalConstraints);
|
||||
this.requestedParameters = requestedParameters;
|
||||
this.pdca = pdca;
|
||||
}
|
||||
|
||||
public PointDataContainer getContainer() {
|
||||
return pdc;
|
||||
}
|
||||
|
||||
/**
|
||||
* For point data need the full data record instead of just a simple db
|
||||
* request, this method handles requesting all the parameters using the
|
||||
* point data API at one time.
|
||||
*/
|
||||
@Override
|
||||
protected void processRequests() throws VizException {
|
||||
List<PointDataLevelNode> nodes = new ArrayList<PointDataLevelNode>();
|
||||
List<String> baseParams = new ArrayList<String>();
|
||||
for (AbstractRequestableNode node : availCache.keySet()) {
|
||||
if (dataCache.containsKey(node)) {
|
||||
continue;
|
||||
}
|
||||
if (node instanceof PointDataLevelNode) {
|
||||
PointDataLevelNode dataNode = (PointDataLevelNode) node;
|
||||
nodes.add(dataNode);
|
||||
baseParams.add(dataNode.getParameter());
|
||||
}
|
||||
}
|
||||
if (baseParams.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (requestedParameters.contains("dataURI")) {
|
||||
baseParams.add("dataURI");
|
||||
}
|
||||
pdc = pdca.getBaseRecords(baseParams, originalConstraints);
|
||||
for (PointDataLevelNode node : nodes) {
|
||||
IDataRecord rec = pdc.getParameterRecord(node.getParameter());
|
||||
Set<AbstractRequestableData> cacheSet = new HashSet<AbstractRequestableData>();
|
||||
cacheSet.add(new PointRequestableData(rec, pdc.getDescription(
|
||||
node.getParameter()).getUnitObject()));
|
||||
dataCache.put(node, cacheSet);
|
||||
if (!Arrays.asList("id", "latitude", "longitude", "dataURI")
|
||||
.contains(rec.getName())) {
|
||||
pdc.remove(rec.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -24,9 +24,11 @@ import javax.measure.unit.Unit;
|
|||
import com.raytheon.uf.common.datastorage.records.IDataRecord;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData;
|
||||
import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
* Wraps a data record from a PointDataContainer in the AbstractRequestableData
|
||||
* api so it can be used in Derived Parameters
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -50,6 +52,8 @@ public class PointRequestableData extends AbstractRequestableData {
|
|||
this.rec = rec;
|
||||
this.level = PointDataInventory.getStationLevel();
|
||||
this.parameter = rec.getName();
|
||||
this.dataTime = TimeAndSpace.TIME_AGNOSTIC;
|
||||
this.space = TimeAndSpace.SPACE_AGNOSTIC;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -110,7 +110,7 @@ public class RadarDataCubeAdapter extends PointDataCubeAdapter {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected PointDataContainer getBaseRecords(
|
||||
public PointDataContainer getBaseRecords(
|
||||
Collection<String> baseParameters,
|
||||
Map<String, RequestConstraint> queryParams) throws VizException {
|
||||
return ((VwpInventory) inventory).getBaseRecords(baseParameters,
|
||||
|
|
Loading…
Add table
Reference in a new issue