Merge "Issue #227 enhanced caching of maps for thin client" into 4-Thin_Client

Former-commit-id: 0608677c67 [formerly 825ddae7e604056e254530e225118f92d88d4b5c]
Former-commit-id: b1810ddd3f
This commit is contained in:
Nate Jensen 2012-02-01 08:45:42 -06:00 committed by Gerrit Code Review
commit 8a0c505bac
12 changed files with 1045 additions and 493 deletions

View file

@ -19,7 +19,6 @@
**/
package com.raytheon.uf.viz.core.maps.rsc;
import java.util.ArrayList;
import java.util.List;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
@ -29,7 +28,6 @@ import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.PixelExtent;
import com.raytheon.uf.viz.core.catalog.DirectDbQuery.QueryLanguage;
import com.raytheon.uf.viz.core.drawables.IFont;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.map.IMapDescriptor;
@ -152,25 +150,10 @@ public abstract class AbstractDbMapResource<T extends AbstractDbMapResourceData,
*/
public List<String> getLabelFields() {
if (this.labelFields == null) {
List<String> labelFields = new ArrayList<String>();
try {
int p = resourceData.getTable().indexOf('.');
String schema = resourceData.getTable().substring(0, p);
String table = resourceData.getTable().substring(p + 1);
StringBuilder query = new StringBuilder(
"SELECT column_name FROM information_schema.columns WHERE table_schema = '");
query.append(schema);
query.append("' AND table_name='");
query.append(table);
query.append("' AND udt_name != 'geometry' ORDER BY ordinal_position;");
List<Object[]> results = MapQueryCache.executeQuery(
query.toString(), "maps", QueryLanguage.SQL);
for (Object[] obj : results) {
labelFields.add(obj[0].toString());
}
this.labelFields = DbMapQueryFactory.getMapQuery(
resourceData.getTable(), resourceData.getGeomField())
.getColumnNamesWithoutGeometries();
ColumnDefinition[] columns = resourceData.getColumns();
if (columns != null) {
for (ColumnDefinition col : columns) {
@ -181,7 +164,6 @@ public abstract class AbstractDbMapResource<T extends AbstractDbMapResourceData,
statusHandler.handle(Priority.PROBLEM,
"Error querying available label fields", e);
}
this.labelFields = labelFields;
}
return this.labelFields;
}

View file

@ -0,0 +1,86 @@
/**
* 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.core.maps.rsc;
import java.util.List;
import com.raytheon.uf.common.dataquery.db.QueryResult;
import com.raytheon.uf.viz.core.exception.VizException;
import com.vividsolutions.jts.geom.Envelope;
/**
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 9, 2011 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class DbMapQueryFactory {
public interface DbMapQuery {
public QueryResult queryWithinEnvelope(Envelope env,
List<String> columns, List<String> additionalConstraints)
throws VizException;
public List<String> getColumnNamesWithoutGeometries()
throws VizException;
public String getGeometryType() throws VizException;
public List<Double> getLevels() throws VizException;
}
private static DbMapQueryFactory instance;
public static DbMapQuery getMapQuery(String table, String geomField) {
return getInstance().getMapQueryInternal(table, geomField);
}
protected static DbMapQueryFactory getInstance() {
if (instance == null) {
instance = new DbMapQueryFactory();
}
return instance;
}
protected static void setCustomInstance(DbMapQueryFactory factory) {
instance = factory;
}
protected DbMapQueryFactory() {
}
protected DbMapQuery getMapQueryInternal(String table, String geomField) {
return new DefaultDbMapQuery(table, geomField);
}
}

View file

@ -53,6 +53,7 @@ import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment;
import com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment;
import com.raytheon.uf.viz.core.PixelExtent;
import com.raytheon.uf.viz.core.catalog.DirectDbQuery;
import com.raytheon.uf.viz.core.catalog.DirectDbQuery.QueryLanguage;
import com.raytheon.uf.viz.core.drawables.IShadedShape;
import com.raytheon.uf.viz.core.drawables.IWireframeShape;
@ -161,18 +162,18 @@ public class DbMapResource extends
String shadingField;
String query;
Envelope envelope;
Map<Object, RGB> colorMap;
Request(IGraphicsTarget target, IMapDescriptor descriptor,
DbMapResource rsc, String query, String geomField,
DbMapResource rsc, Envelope envelope, String geomField,
String labelField, String shadingField,
Map<Object, RGB> colorMap) {
this.target = target;
this.descriptor = descriptor;
this.rsc = rsc;
this.query = query;
this.envelope = envelope;
this.geomField = geomField;
this.labelField = labelField;
this.shadingField = shadingField;
@ -207,9 +208,9 @@ public class DbMapResource extends
public Throwable cause;
public String query;
public Envelope query;
private Result(String query) {
private Result(Envelope query) {
this.query = query;
failed = true;
}
@ -228,7 +229,7 @@ public class DbMapResource extends
}
public void request(IGraphicsTarget target, IMapDescriptor descriptor,
DbMapResource rsc, String query, String geomField,
DbMapResource rsc, Envelope query, String geomField,
String labelField, String shadingField,
Map<Object, RGB> colorMap) {
if (requestQueue.size() == QUEUE_LIMIT) {
@ -255,7 +256,7 @@ public class DbMapResource extends
protected IStatus run(IProgressMonitor monitor) {
Request req = requestQueue.poll();
while (req != null) {
Result result = new Result(req.query);
Result result = new Result(req.envelope);
try {
String table = resourceData.getTable();
if (canceled) {
@ -263,10 +264,35 @@ public class DbMapResource extends
result = null;
return Status.CANCEL_STATUS;
}
QueryResult mappedResult = MapQueryCache
.executeMappedQuery(req.query, "maps",
QueryLanguage.SQL);
List<String> constraints = new ArrayList<String>();
if (resourceData.getConstraints() != null) {
constraints.addAll(Arrays.asList(resourceData
.getConstraints()));
}
List<String> fields = new ArrayList<String>();
fields.add(GID);
if (req.labelField != null
&& !fields.contains(req.labelField)) {
fields.add(req.labelField);
}
if (req.shadingField != null
&& !fields.contains(req.shadingField)) {
fields.add(req.shadingField);
}
if (resourceData.getColumns() != null) {
for (ColumnDefinition column : resourceData
.getColumns()) {
if (fields.contains(column.getName())) {
fields.remove(column.getName());
}
fields.add(column.toString());
}
}
QueryResult mappedResult = DbMapQueryFactory.getMapQuery(
resourceData.getTable(),
resourceData.getGeomField()).queryWithinEnvelope(
req.envelope, fields, constraints);
Map<Integer, Geometry> gidMap = new HashMap<Integer, Geometry>(
mappedResult.getResultCount() * 2);
List<Integer> toRequest = new ArrayList<Integer>(
@ -309,7 +335,7 @@ public class DbMapResource extends
result = null;
return Status.CANCEL_STATUS;
}
QueryResult geomResults = MapQueryCache
QueryResult geomResults = DirectDbQuery
.executeMappedQuery(geomQuery.toString(),
"maps", QueryLanguage.SQL);
for (int i = 0; i < geomResults.getResultCount(); ++i) {
@ -330,7 +356,7 @@ public class DbMapResource extends
"Expected byte[] received "
+ obj.getClass().getName()
+ ": " + obj.toString()
+ "\n query=\"" + req.query
+ "\n query=\"" + req.envelope
+ "\"");
}
gidMap.put(gid, g);
@ -525,7 +551,7 @@ public class DbMapResource extends
getLabelFields().toArray(new String[0]));
}
private String buildQuery(PixelExtent extent) throws VizException {
private Envelope buildEnvelope(PixelExtent extent) throws VizException {
Envelope env = null;
try {
Envelope e = descriptor.pixelToWorld(extent, descriptor.getCRS());
@ -535,60 +561,7 @@ public class DbMapResource extends
} catch (Exception e) {
throw new VizException("Error transforming extent", e);
}
double[] levels = getLevels();
String geometryField = getGeomField(levels[levels.length - 1]);
// get the geometry field
StringBuilder query = new StringBuilder("SELECT ");
query.append(GID);
// add any additional columns
List<String> additionalColumns = new ArrayList<String>();
if (resourceData.getColumns() != null) {
for (ColumnDefinition column : resourceData.getColumns()) {
query.append(", ");
query.append(column);
additionalColumns.add(column.getName());
}
}
// add the label field
String labelField = getCapability(LabelableCapability.class)
.getLabelField();
if (labelField != null && !additionalColumns.contains(labelField)) {
query.append(", ");
query.append(labelField);
}
// add the shading field
String shadingField = getCapability(ShadeableCapability.class)
.getShadingField();
if (shadingField != null && !additionalColumns.contains(shadingField)) {
query.append(", ");
query.append(shadingField);
}
// add the geometry table
query.append(" FROM ");
query.append(resourceData.getTable());
// add the geospatial constraint
query.append(" WHERE ");
query.append(getGeospatialConstraint(geometryField, env));
// add any additional constraints
if (resourceData.getConstraints() != null) {
for (String constraint : resourceData.getConstraints()) {
query.append(" AND ");
query.append(constraint);
}
}
query.append(';');
return query.toString();
return env;
}
protected String getGeomField(double simpLev) {
@ -599,18 +572,6 @@ public class DbMapResource extends
return resourceData.getGeomField() + suffix;
}
/**
* @return
*/
protected Object getGeospatialConstraint(String geometryField, Envelope env) {
// create the geospatial constraint from the envelope
String geoConstraint = String.format(
"%s && ST_SetSrid('BOX3D(%f %f, %f %f)'::box3d,4326)",
geometryField, env.getMinX(), env.getMinY(), env.getMaxX(),
env.getMaxY());
return geoConstraint;
}
/**
* @param dpp
* @return
@ -665,7 +626,7 @@ public class DbMapResource extends
clipToProjExtent(screenExtent).getEnvelope())) {
if (!paintProps.isZooming()) {
PixelExtent expandedExtent = getExpandedExtent(screenExtent);
String query = buildQuery(expandedExtent);
Envelope query = buildEnvelope(expandedExtent);
queryJob.request(aTarget, descriptor, this, query,
getGeomField(simpLev), labelField, shadingField,
colorMap);
@ -856,27 +817,13 @@ public class DbMapResource extends
protected double[] getLevels() {
if (levels == null) {
try {
int p = resourceData.getTable().indexOf('.');
String schema = resourceData.getTable().substring(0, p);
String table = resourceData.getTable().substring(p + 1);
StringBuilder query = new StringBuilder(
"SELECT f_geometry_column FROM public.geometry_columns WHERE f_table_schema='");
query.append(schema);
query.append("' AND f_table_name='");
query.append(table);
query.append("' AND f_geometry_column LIKE '");
query.append(resourceData.getGeomField());
query.append("_%';");
List<Object[]> results = MapQueryCache.executeQuery(
query.toString(), "maps", QueryLanguage.SQL);
List<Double> results = DbMapQueryFactory.getMapQuery(
resourceData.getTable(), resourceData.getGeomField())
.getLevels();
levels = new double[results.size()];
int i = 0;
for (Object[] objs : results) {
String s = ((String) objs[0]).substring(
resourceData.getGeomField().length() + 1).replace(
'_', '.');
levels[i++] = Double.parseDouble(s);
for (Double d : results) {
levels[i++] = d;
}
Arrays.sort(levels);
} catch (VizException e) {
@ -891,19 +838,9 @@ public class DbMapResource extends
protected String getGeometryType() {
if (geometryType == null) {
try {
int p = resourceData.getTable().indexOf('.');
String schema = resourceData.getTable().substring(0, p);
String table = resourceData.getTable().substring(p + 1);
StringBuilder query = new StringBuilder(
"SELECT type FROM geometry_columns WHERE f_table_schema='");
query.append(schema);
query.append("' AND f_table_name='");
query.append(table);
query.append("' LIMIT 1;");
List<Object[]> results = MapQueryCache.executeQuery(
query.toString(), "maps", QueryLanguage.SQL);
geometryType = (String) results.get(0)[0];
geometryType = DbMapQueryFactory.getMapQuery(
resourceData.getTable(), resourceData.getGeomField())
.getGeometryType();
} catch (Throwable e) {
statusHandler.handle(Priority.PROBLEM,
"Error querying geometry type", e);

View file

@ -22,6 +22,7 @@ package com.raytheon.uf.viz.core.maps.rsc;
import java.awt.geom.Rectangle2D;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
@ -32,6 +33,7 @@ import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.swt.graphics.RGB;
import org.geotools.geometry.jts.ReferencedEnvelope;
import com.raytheon.uf.common.dataquery.db.QueryResult;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.pointdata.vadriver.VA_Advanced;
@ -45,7 +47,6 @@ import com.raytheon.uf.viz.core.IGraphicsTarget.PointStyle;
import com.raytheon.uf.viz.core.IGraphicsTarget.TextStyle;
import com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment;
import com.raytheon.uf.viz.core.PixelExtent;
import com.raytheon.uf.viz.core.catalog.DirectDbQuery.QueryLanguage;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.map.MapDescriptor;
@ -158,18 +159,19 @@ public class DbPointMapResource extends
private class Request {
DbPointMapResource rsc;
boolean labeled;
String labelField;
boolean useGoodness;
String goodnessField;
String query;
Envelope env;
Request(DbPointMapResource rsc, String query, boolean labeled,
boolean useGoodness) {
public Request(DbPointMapResource rsc, String labelField,
String goodnessField, Envelope env) {
super();
this.rsc = rsc;
this.query = query;
this.labeled = labeled;
this.useGoodness = useGoodness;
this.labelField = labelField;
this.goodnessField = goodnessField;
this.env = env;
}
}
@ -200,11 +202,12 @@ public class DbPointMapResource extends
}
public void request(IGraphicsTarget target, DbPointMapResource rsc,
String query, boolean labeled, boolean useGoodness) {
Envelope envelope, String labelField, String goodnessField) {
if (requestQueue.size() == QUEUE_LIMIT) {
requestQueue.poll();
}
requestQueue.add(new Request(rsc, query, labeled, useGoodness));
requestQueue.add(new Request(rsc, labelField, goodnessField,
envelope));
this.cancel();
this.schedule();
@ -226,10 +229,37 @@ public class DbPointMapResource extends
while (req != null) {
Result result = new Result();
try {
System.out.println(req.query);
long t0 = System.currentTimeMillis();
List<Object[]> results = MapQueryCache.executeQuery(
req.query, "maps", QueryLanguage.SQL);
List<String> columns = new ArrayList<String>();
if (req.labelField != null) {
columns.add(req.labelField);
}
if (req.goodnessField != null
&& req.goodnessField != req.labelField) {
columns.add(req.goodnessField);
}
if (resourceData.getColumns() != null) {
for (ColumnDefinition column : resourceData
.getColumns()) {
if (columns.contains(column.getName())) {
columns.remove(column.getName());
}
columns.add(column.toString());
}
}
columns.add("AsBinary(" + resourceData.getGeomField()
+ ") as " + resourceData.getGeomField());
List<String> constraints = null;
if (resourceData.getConstraints() != null) {
constraints = Arrays.asList(resourceData
.getConstraints());
}
QueryResult results = DbMapQueryFactory.getMapQuery(
resourceData.getTable(),
resourceData.getGeomField()).queryWithinEnvelope(
req.env, columns, constraints);
long t1 = System.currentTimeMillis();
System.out.println("Maps DB query took: " + (t1 - t0)
@ -238,41 +268,48 @@ public class DbPointMapResource extends
List<LabelNode> newLabels = new ArrayList<LabelNode>();
WKBReader wkbReader = new WKBReader();
for (Object[] r : results) {
for (int c = 0; c < results.getResultCount(); c++) {
if (canceled) {
canceled = false;
result = null;
// System.out.println("MapQueryJob Canceled.");
return Status.CANCEL_STATUS;
}
int i = 0;
Geometry g = null;
if (r[i] instanceof byte[]) {
byte[] wkb = (byte[]) r[i++];
Object geomObj = results.getRowColumnValue(c,
resourceData.getGeomField());
if (geomObj instanceof byte[]) {
byte[] wkb = (byte[]) geomObj;
g = wkbReader.read(wkb);
} else {
statusHandler.handle(Priority.ERROR,
"Expected byte[] received "
+ r[i].getClass().getName() + ": "
+ r[i].toString() + "\n query=\""
+ req.query + "\"");
+ geomObj.getClass().getName()
+ ": " + geomObj.toString()
+ "\n query=\"" + req.env + "\"");
}
if (g != null) {
String label = "";
if (req.labeled && r[i] != null) {
if (r[i] instanceof BigDecimal) {
label = Double.toString(((Number) r[i++])
if (req.labelField != null
&& results.getRowColumnValue(c,
req.labelField) != null) {
Object r = results.getRowColumnValue(c,
req.labelField);
if (r instanceof BigDecimal) {
label = Double.toString(((Number) r)
.doubleValue());
} else {
label = r[i++].toString();
label = r.toString();
}
}
LabelNode node = new LabelNode(label,
g.getCentroid());
if (req.useGoodness) {
node.setGoodness(((Number) r[i++]).intValue());
if (req.goodnessField != null) {
node.setGoodness(((Number) results
.getRowColumnValue(c, req.goodnessField))
.intValue());
}
newLabels.add(node);
}
@ -293,7 +330,7 @@ public class DbPointMapResource extends
}
Double[] distances;
if (req.useGoodness) {
if (req.goodnessField != null) {
distances = distanceCalc.getVaAdvanced(coords,
goodness, dst);
} else {
@ -358,7 +395,7 @@ public class DbPointMapResource extends
queryJob = new MapQueryJob();
}
private String buildQuery(IGraphicsTarget target, PixelExtent extent)
private void requestData(IGraphicsTarget target, PixelExtent extent)
throws VizException {
Envelope env = null;
@ -370,62 +407,13 @@ public class DbPointMapResource extends
} catch (Exception e) {
throw new VizException("Error transforming extent", e);
}
// System.out.println(env);
String geometryField = resourceData.getGeomField();
// create the geospatial constraint from the envelope
String geoConstraint = String.format(
"%s && ST_SetSrid('BOX3D(%f %f, %f %f)'::box3d,4326)",
geometryField, env.getMinX(), env.getMinY(), env.getMaxX(),
env.getMaxY());
// get the geometry field
StringBuilder query = new StringBuilder("SELECT AsBinary(");
query.append(geometryField);
query.append(")");
// add the label field
String labelField = getCapability(LabelableCapability.class)
.getLabelField();
if (labelField != null) {
query.append(", ");
query.append(labelField);
}
// add the goodness field
if (resourceData.getGoodnessField() != null) {
query.append(", ");
query.append(resourceData.getGoodnessField());
}
// add any additional columns
if (resourceData.getColumns() != null) {
for (ColumnDefinition column : resourceData.getColumns()) {
query.append(", ");
query.append(column);
}
}
// add the geometry table
query.append(" FROM ");
query.append(resourceData.getTable());
// add the geo constraint
query.append(" WHERE ");
query.append(geoConstraint);
// add any addtional constraints
if (resourceData.getConstraints() != null) {
for (String constraint : resourceData.getConstraints()) {
query.append(" AND ");
query.append(constraint);
}
}
query.append(';');
return query.toString();
queryJob.request(target, this, env, labelField,
resourceData.getGoodnessField());
}
@Override
@ -454,9 +442,7 @@ public class DbPointMapResource extends
clipToProjExtent(screenExtent).getEnvelope())) {
if (!paintProps.isZooming()) {
PixelExtent expandedExtent = getExpandedExtent(screenExtent);
String query = buildQuery(aTarget, expandedExtent);
queryJob.request(aTarget, this, query, isLabeled,
resourceData.getGoodnessField() != null);
requestData(aTarget, expandedExtent);
lastExtent = expandedExtent;
lastLabelField = labelField;
}

View file

@ -0,0 +1,178 @@
/**
* 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.core.maps.rsc;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.raytheon.uf.common.dataquery.db.QueryResult;
import com.raytheon.uf.viz.core.catalog.DirectDbQuery;
import com.raytheon.uf.viz.core.catalog.DirectDbQuery.QueryLanguage;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.maps.rsc.DbMapQueryFactory.DbMapQuery;
import com.vividsolutions.jts.geom.Envelope;
/**
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 9, 2011 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class DefaultDbMapQuery implements DbMapQuery {
protected static final String MAPS = "maps";
protected final String table;
protected final String geomField;
protected DefaultDbMapQuery(String table, String geomField) {
this.table = table;
this.geomField = geomField;
}
@Override
public QueryResult queryWithinEnvelope(Envelope env, List<String> columns,
List<String> additionalConstraints) throws VizException {
// add the geospatial constraint
if (env != null) {
// copy before modifying
if (additionalConstraints == null) {
additionalConstraints = new ArrayList<String>();
} else {
additionalConstraints = new ArrayList<String>(
additionalConstraints);
}
// geospatial constraint will be first
additionalConstraints.add(0, String.format(
"%s && ST_SetSrid('BOX3D(%f %f, %f %f)'::box3d,4326)",
geomField, env.getMinX(), env.getMinY(), env.getMaxX(),
env.getMaxY()));
}
StringBuilder query = new StringBuilder("SELECT ");
if (columns != null && !columns.isEmpty()) {
Iterator<String> iter = columns.iterator();
query.append(iter.next());
while (iter.hasNext()) {
query.append(", ");
query.append(iter.next());
}
}
query.append(" FROM ");
query.append(table);
// add any additional constraints
if (additionalConstraints != null && !additionalConstraints.isEmpty()) {
query.append(" WHERE ");
Iterator<String> iter = additionalConstraints.iterator();
query.append(iter.next());
while (iter.hasNext()) {
query.append(" AND ");
query.append(iter.next());
}
}
query.append(';');
return DirectDbQuery.executeMappedQuery(query.toString(), MAPS,
QueryLanguage.SQL);
}
@Override
public List<String> getColumnNamesWithoutGeometries() throws VizException {
List<String> labelFields = new ArrayList<String>();
int p = table.indexOf('.');
String schema = table.substring(0, p);
String table = this.table.substring(p + 1);
StringBuilder query = new StringBuilder(
"SELECT column_name FROM information_schema.columns WHERE table_schema = '");
query.append(schema);
query.append("' AND table_name='");
query.append(table);
query.append("' ");
query.append("AND udt_name != 'geometry' ");
query.append("ORDER BY ordinal_position;");
List<Object[]> results = DirectDbQuery.executeQuery(query.toString(),
MAPS, QueryLanguage.SQL);
for (Object[] obj : results) {
labelFields.add(obj[0].toString());
}
return labelFields;
}
@Override
public String getGeometryType() throws VizException {
int p = table.indexOf('.');
String schema = table.substring(0, p);
String table = this.table.substring(p + 1);
StringBuilder query = new StringBuilder(
"SELECT type FROM geometry_columns WHERE f_table_schema='");
query.append(schema);
query.append("' AND f_table_name='");
query.append(table);
query.append("' LIMIT 1;");
List<Object[]> results = DirectDbQuery.executeQuery(query.toString(),
MAPS, QueryLanguage.SQL);
return (String) results.get(0)[0];
}
@Override
public List<Double> getLevels() throws VizException {
int p = table.indexOf('.');
String schema = table.substring(0, p);
String table = this.table.substring(p + 1);
StringBuilder query = new StringBuilder(
"SELECT f_geometry_column FROM public.geometry_columns WHERE f_table_schema='");
query.append(schema);
query.append("' AND f_table_name='");
query.append(table);
query.append("' AND f_geometry_column LIKE '");
query.append(geomField);
query.append("_%';");
List<Object[]> results = DirectDbQuery.executeQuery(query.toString(),
MAPS, QueryLanguage.SQL);
List<Double> levels = new ArrayList<Double>(results.size());
for (Object[] objs : results) {
String s = (String) objs[0];
s = s.replace(geomField + "_", "");
s = s.replace('_', '.');
levels.add(Double.parseDouble(s));
}
return levels;
}
}

View file

@ -1,269 +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.core.maps.rsc;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
import com.raytheon.uf.common.dataquery.db.QueryResult;
import com.raytheon.uf.common.dataquery.db.QueryResultRow;
import com.raytheon.uf.common.localization.FileLocker;
import com.raytheon.uf.common.localization.FileLocker.Type;
import com.raytheon.uf.common.serialization.DynamicSerializationManager;
import com.raytheon.uf.common.serialization.DynamicSerializationManager.SerializationType;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.util.cache.ICacheObject;
import com.raytheon.uf.common.util.cache.LRUCache;
import com.raytheon.uf.viz.core.catalog.DirectDbQuery;
import com.raytheon.uf.viz.core.catalog.DirectDbQuery.QueryLanguage;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.maps.rsc.MapQueryCache.QueryCacheable;
/**
* Map query caching derived from Erik Magnuson's code changes to DirectDbQuery
* to keep map results around on the client and not waste time/bandwidth
* querying.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 9, 2011 njensen Initial creation
*
* </pre>
*
* @author njensen
* @version 1.0
*/
public class MapQueryCache extends LRUCache<String, QueryCacheable> {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(MapQueryCache.class);
private static MapQueryCache mapQueryCache = new MapQueryCache(
64 * 1024 * 1024);
private static boolean cache = false;
@DynamicSerialize
protected static class QueryCacheable implements ICacheObject {
@DynamicSerializeElement
QueryResult queryResult;
public QueryCacheable() {
}
protected QueryCacheable(QueryResult result) {
queryResult = result;
}
@Override
public int getSize() {
// TODO get better number or move this off LRU
return queryResult.getColumnCount() * queryResult.getRows().length
* 4;
}
public QueryResult getQueryResult() {
return queryResult;
}
public void setQueryResult(QueryResult queryResult) {
this.queryResult = queryResult;
}
}
@DynamicSerialize
protected static class CachePair {
@DynamicSerializeElement
String queryKey;
@DynamicSerializeElement
QueryCacheable cacheable;
public CachePair() {
}
protected CachePair(String key, QueryCacheable obj) {
this.queryKey = key;
this.cacheable = obj;
}
public String getQueryKey() {
return queryKey;
}
public void setQueryKey(String queryKey) {
this.queryKey = queryKey;
}
public QueryCacheable getCacheable() {
return cacheable;
}
public void setCacheable(QueryCacheable cacheable) {
this.cacheable = cacheable;
}
}
/**
* Private constructor
*
* @param maxSize
*/
private MapQueryCache(long maxSize) {
super(maxSize);
}
/**
* Executes a mapped query against DirectDbQuery API. If cache is enabled
* will check the cache before sending a query and if sending a query, will
* store the result in the cache.
*
* @param query
* @param database
* @param language
* @return
* @throws VizException
*/
public static QueryResult executeMappedQuery(String query, String database,
QueryLanguage language) throws VizException {
QueryResult queryResult = null;
String key = query + database + language;
if (cache) {
QueryCacheable cacheResult = mapQueryCache.get(key);
if (cacheResult != null) {
queryResult = cacheResult.queryResult;
}
}
if (queryResult == null) {
// either cache was disabled, it wasn't in cache, or reading cache
// failed, so send the query
queryResult = DirectDbQuery.executeMappedQuery(query, database,
language);
if (cache) {
mapQueryCache.put(key, new QueryCacheable(queryResult));
}
}
return queryResult;
}
/**
* Executes a query against DirectDbQuery API. If cache is enabled will
* check the cache before sending a query and if sending a query, will store
* the result in the cache.
*
* @param query
* @param database
* @param language
* @return
* @throws VizException
*/
public static List<Object[]> executeQuery(String query, String database,
QueryLanguage language) throws VizException {
QueryResult result = executeMappedQuery(query, database, language);
List<Object[]> unmappedResults = new ArrayList<Object[]>();
for (QueryResultRow row : result.getRows()) {
unmappedResults.add(row.getColumnValues());
}
return unmappedResults;
}
public static void setCaching(boolean caching) {
cache = caching;
}
private Collection<CachePair> getCacheables() {
List<CachePair> pairs = new ArrayList<CachePair>(lruMap.size());
synchronized (this) {
for (Entry<String, Item> entry : lruMap.entrySet()) {
pairs.add(new CachePair(entry.getKey(), entry.getValue().value));
}
}
return pairs;
}
private void setCacheables(Collection<CachePair> pairs) {
for (CachePair pair : pairs) {
put(pair.queryKey, pair.cacheable);
}
}
/**
* Restore the geometry cache from the file system
*/
@SuppressWarnings("unchecked")
public static synchronized void restoreCache(File cacheFile) {
try {
FileLocker.lock(MapQueryCache.class, cacheFile, Type.READ);
if (cacheFile.exists() && cacheFile.length() > 0) {
FileInputStream fin = new FileInputStream(cacheFile);
Collection<CachePair> pairs = (Collection<CachePair>) DynamicSerializationManager
.getManager(SerializationType.Thrift).deserialize(fin);
mapQueryCache.setCacheables(pairs);
}
} catch (Exception e) {
statusHandler.error("Error restoring cache from file system", e);
e.printStackTrace();
} finally {
FileLocker.unlock(MapQueryCache.class, cacheFile);
}
}
/**
* Store the geometry cache to the file system
*/
public static synchronized void storeCache(File cacheFile) {
try {
FileLocker.lock(MapQueryCache.class, cacheFile, Type.WRITE);
FileOutputStream out = new FileOutputStream(cacheFile);
DynamicSerializationManager.getManager(SerializationType.Thrift)
.serialize(mapQueryCache.getCacheables(), out);
out.close();
} catch (Exception e) {
statusHandler.error("Error storing cache to file system", e);
e.printStackTrace();
} finally {
FileLocker.unlock(MapQueryCache.class, cacheFile);
}
}
}

View file

@ -17,6 +17,10 @@ Require-Bundle: com.raytheon.uf.viz.core,
Import-Package: com.raytheon.uf.common.comm,
com.raytheon.uf.common.datastorage,
com.raytheon.uf.viz.core.maps.rsc,
com.vividsolutions.jts.geom,
com.vividsolutions.jts.index.strtree,
com.vividsolutions.jts.io,
javax.jms
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Export-Package: com.raytheon.uf.viz.thinclient.cave.cache.map

View file

@ -21,8 +21,8 @@ package com.raytheon.uf.viz.thinclient.cave.cache;
import java.io.File;
import com.raytheon.uf.viz.core.maps.rsc.MapQueryCache;
import com.raytheon.uf.viz.thinclient.cache.AbstractCachePersistance;
import com.raytheon.uf.viz.thinclient.cave.cache.map.CacheDbMapQueryFactory;
import com.raytheon.uf.viz.thinclient.preferences.ThinClientPreferenceConstants;
/**
@ -57,7 +57,8 @@ public class MapQueryCachePersistence extends AbstractCachePersistance {
*/
@Override
public void store(File cacheFile) {
MapQueryCache.storeCache(cacheFile);
CacheDbMapQueryFactory.storeCache(cacheFile);
// MapQueryCache.storeCache(cacheFile);
}
/*
@ -69,7 +70,8 @@ public class MapQueryCachePersistence extends AbstractCachePersistance {
*/
@Override
public void restore(File cacheFile) {
MapQueryCache.restoreCache(cacheFile);
CacheDbMapQueryFactory.restoreCache(cacheFile);
// MapQueryCache.restoreCache(cacheFile);
}
@ -81,7 +83,7 @@ public class MapQueryCachePersistence extends AbstractCachePersistance {
*/
@Override
protected void enable() {
MapQueryCache.setCaching(true);
CacheDbMapQueryFactory.setEnableCaching(true);
}
/*
@ -92,7 +94,7 @@ public class MapQueryCachePersistence extends AbstractCachePersistance {
*/
@Override
protected void disable() {
MapQueryCache.setCaching(false);
CacheDbMapQueryFactory.setEnableCaching(false);
}
}

View file

@ -0,0 +1,327 @@
/**
* 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.thinclient.cave.cache.map;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.raytheon.uf.common.dataquery.db.QueryResult;
import com.raytheon.uf.common.dataquery.db.QueryResultRow;
import com.raytheon.uf.viz.core.catalog.DirectDbQuery;
import com.raytheon.uf.viz.core.catalog.DirectDbQuery.QueryLanguage;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.maps.rsc.DefaultDbMapQuery;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.index.strtree.STRtree;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKBReader;
/**
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 9, 2011 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class CacheDbMapQuery extends DefaultDbMapQuery {
private static final String GID = "gid";
private static final String GEOM_ENV = "geom_env";
// Used for spatial lookups, returns a list of indexes into the data
private STRtree tree;
// all database columns for every row, this is the primary cached data.
private QueryResult data = null;
// a specific list of indexes which are returned for any given constraint
private Map<String, List<Integer>> constraint2indices = new HashMap<String, List<Integer>>();
// The column names available without any geometry columns.
private List<String> columnNames = null;
// the geometry type
private String geometryType = null;;
// all levels for a the geometry
private List<Double> levels = null;
private Object columnNamesLock = new Object();
private Object geometryTypeLock = new Object();
private Object levelsLock = new Object();
protected CacheDbMapQuery(String table, String geomField) {
super(table, geomField);
}
protected CacheDbMapQuery(CacheDbMapQuerySerializeable s)
throws VizException {
super(s.getTable(), s.getGeomField());
geometryType = s.getGeometryType();
columnNames = s.getColumnNames();
levels = s.getLevels();
constraint2indices = s.getConstraint2indices();
data = s.getData();
if (data != null) {
createTree();
}
}
@Override
public QueryResult queryWithinEnvelope(Envelope env, List<String> columns,
List<String> additionalConstraints) throws VizException {
fillCache(geomField, columns);
List<?> items = tree.query(env);
List<Integer> validGIDs = null;
if (additionalConstraints != null) {
for (String constraint : additionalConstraints) {
items.retainAll(getIndices(constraint));
}
}
List<QueryResultRow> rows = new ArrayList<QueryResultRow>();
for (int i = 0; i < items.size(); i++) {
int rowNumber = (Integer) items.get(i);
if (validGIDs != null
&& !validGIDs.contains(data.getRowColumnValue(rowNumber,
GID))) {
continue;
}
Object[] columnValues = new Object[columns.size()];
for (int j = 0; j < columns.size(); j++) {
columnValues[j] = data.getRowColumnValue(rowNumber,
columns.get(j));
}
rows.add(new QueryResultRow(columnValues));
}
Map<String, Integer> columnNames = new HashMap<String, Integer>();
for (int i = 0; i < columns.size(); i++) {
columnNames.put(doAs(columns.get(i)), i);
}
return new QueryResult(columnNames, rows.toArray(new QueryResultRow[0]));
}
private List<Integer> getIndices(String constraint) throws VizException {
synchronized (constraint2indices) {
List<Integer> indices = constraint2indices.get(constraint);
if (indices != null) {
return indices;
}
StringBuilder query = new StringBuilder("SELECT ");
query.append(GID);
query.append(" FROM ");
query.append(table);
query.append(" WHERE ");
query.append(constraint);
query.append(";");
List<Object[]> results = DirectDbQuery.executeQuery(
query.toString(), MAPS, QueryLanguage.SQL);
ArrayList<Integer> gids = new ArrayList<Integer>(results.size());
for (Object[] result : results) {
gids.add((Integer) result[0]);
}
indices = new ArrayList<Integer>(gids.size());
for (int i = 0; i < data.getResultCount(); ++i) {
int gid = (Integer) data.getRowColumnValue(i, "gid");
if (gids.contains(gid)) {
indices.add(i);
}
}
constraint2indices.put(constraint, indices);
return indices;
}
}
private QueryResult getColumns(List<String> columns) throws VizException {
StringBuilder query = new StringBuilder("SELECT ");
Iterator<String> iter = columns.iterator();
query.append(iter.next());
while (iter.hasNext()) {
query.append(", ");
query.append(iter.next());
}
query.append(" from ");
query.append(table);
query.append(";");
QueryResult result = DirectDbQuery.executeMappedQuery(query.toString(),
MAPS, QueryLanguage.SQL);
for (String column : columns) {
String as = doAs(column);
if (as.equals(column)) {
continue;
}
if (GEOM_ENV.equals(as)) {
continue;
}
int index = result.getColumnNames().remove(doAs(column));
result.getColumnNames().put(column, index);
}
return result;
}
private synchronized void fillCache(String geomField, List<String> columns)
throws VizException {
columns = new ArrayList<String>(columns);
if (data != null) {
for (String column : data.getColumnNames().keySet()) {
columns.remove(column);
}
}
if (columns.isEmpty()) {
return;
}
// we correlate data based off gid so make sure it is in there.
if (!columns.contains("gid")) {
columns.add("gid");
}
if (tree == null) {
// request the envelope
String envColumn = "AsBinary(ST_Envelope(" + geomField + ")) as "
+ GEOM_ENV;
columns.add(envColumn);
QueryResult result = getColumns(columns);
columns.remove(envColumn);
data = result;
createTree();
} else {
QueryResult result = getColumns(columns);
// gid should already be in the result set.
columns.remove("gid");
Map<Integer, QueryResultRow> gid2row = new HashMap<Integer, QueryResultRow>();
for (int i = 0; i < result.getResultCount(); ++i) {
int gid = (Integer) result.getRowColumnValue(i, "gid");
gid2row.put(gid, result.getRows()[i]);
}
int index = data.getColumnNames().size();
for (String column : columns) {
data.getColumnNames().put(column, index++);
}
for (int i = 0; i < data.getResultCount(); ++i) {
int gid = (Integer) data.getRowColumnValue(i, "gid");
QueryResultRow existRow = data.getRows()[i];
QueryResultRow resultRow = gid2row.get(gid);
Object[] columnValues = existRow.getColumnValues();
columnValues = Arrays.copyOf(columnValues, columnValues.length
+ columns.size());
for (String column : columns) {
int resultIndex = result.getColumnNames().get(column);
int newIndex = data.getColumnNames().get(column);
columnValues[newIndex] = resultRow.getColumn(resultIndex);
}
existRow.setColumnValues(columnValues);
}
}
}
private void createTree() throws VizException {
WKBReader wkbReader = new WKBReader();
tree = new STRtree();
try {
for (int i = 0; i < data.getResultCount(); ++i) {
Object obj = data.getRowColumnValue(i, GEOM_ENV);
if (obj instanceof byte[]) {
byte[] wkb = (byte[]) obj;
Geometry g = wkbReader.read(wkb);
Envelope e = g.getEnvelopeInternal();
tree.insert(e, i);
} else {
throw new VizException("Error populating GID Cache.");
}
}
} catch (ParseException e) {
throw new VizException(e);
}
}
private String doAs(String string) {
String[] split = string.split("\\s[aA][sS]\\s");
return split[split.length - 1].trim().toLowerCase();
}
@Override
public List<String> getColumnNamesWithoutGeometries() throws VizException {
synchronized (columnNamesLock) {
if (columnNames == null) {
columnNames = super.getColumnNamesWithoutGeometries();
}
return new ArrayList<String>(columnNames);
}
}
@Override
public String getGeometryType() throws VizException {
synchronized (geometryTypeLock) {
if (geometryType == null) {
geometryType = super.getGeometryType();
}
return geometryType;
}
}
@Override
public List<Double> getLevels() throws VizException {
synchronized (levelsLock) {
if (levels == null) {
levels = super.getLevels();
}
return levels;
}
}
protected CacheDbMapQuerySerializeable getSerializeable() {
CacheDbMapQuerySerializeable s = new CacheDbMapQuerySerializeable();
s.setTable(table);
s.setGeomField(geomField);
s.setGeometryType(geometryType);
s.setColumnNames(columnNames);
s.setLevels(levels);
s.setConstraint2indices(constraint2indices);
s.setData(data);
return s;
}
protected String getTable() {
return table;
}
protected String getGeomField() {
return geomField;
}
}

View file

@ -0,0 +1,145 @@
/**
* 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.thinclient.cave.cache.map;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.raytheon.uf.common.localization.FileLocker;
import com.raytheon.uf.common.localization.FileLocker.Type;
import com.raytheon.uf.common.serialization.DynamicSerializationManager;
import com.raytheon.uf.common.serialization.DynamicSerializationManager.SerializationType;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.viz.core.maps.rsc.DbMapQueryFactory;
/**
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 9, 2011 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class CacheDbMapQueryFactory extends DbMapQueryFactory {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(CacheDbMapQueryFactory.class);
private static CacheDbMapQueryFactory instance;
private Map<String, CacheDbMapQuery> cache = new HashMap<String, CacheDbMapQuery>();
@Override
protected CacheDbMapQuery getMapQueryInternal(String table, String geomField) {
String key = table + ":::" + geomField;
synchronized (cache) {
CacheDbMapQuery query = cache.get(key);
if (query == null) {
query = new CacheDbMapQuery(table, geomField);
cache.put(key, query);
}
return query;
}
}
public static synchronized void setEnableCaching(boolean enabled) {
if (enabled) {
if (instance == null) {
instance = new CacheDbMapQueryFactory();
}
setCustomInstance(instance);
} else {
setCustomInstance(null);
}
}
public static synchronized void restoreCache(File cacheFile) {
if (instance == null) {
setCustomInstance(instance = new CacheDbMapQueryFactory());
}
synchronized (instance.cache) {
try {
FileLocker.lock(CacheDbMapQuery.class, cacheFile, Type.READ);
if (cacheFile.exists() && cacheFile.length() > 0) {
FileInputStream fin = new FileInputStream(cacheFile);
List<CacheDbMapQuerySerializeable> list = (List<CacheDbMapQuerySerializeable>) DynamicSerializationManager
.getManager(SerializationType.Thrift).deserialize(
fin);
for (CacheDbMapQuerySerializeable s : list) {
CacheDbMapQuery c = new CacheDbMapQuery(s);
String key = c.getTable() + ":::" + c.getGeomField();
instance.cache.put(key, c);
}
}
} catch (Exception e) {
statusHandler
.error("Error restoring cache from file system", e);
e.printStackTrace();
} finally {
FileLocker.unlock(CacheDbMapQuery.class, cacheFile);
}
}
}
/**
* Store the geometry cache to the file system
*/
public static synchronized void storeCache(File cacheFile) {
if (instance == null) {
return;
}
synchronized (instance.cache) {
try {
FileLocker.lock(CacheDbMapQuery.class, cacheFile, Type.WRITE);
FileOutputStream out = new FileOutputStream(cacheFile);
List<CacheDbMapQuerySerializeable> list = new ArrayList<CacheDbMapQuerySerializeable>(
instance.cache.size());
for (CacheDbMapQuery value : instance.cache.values()) {
list.add(value.getSerializeable());
}
DynamicSerializationManager
.getManager(SerializationType.Thrift).serialize(list,
out);
out.close();
} catch (Exception e) {
statusHandler.error("Error storing cache to file system", e);
e.printStackTrace();
} finally {
FileLocker.unlock(CacheDbMapQuery.class, cacheFile);
}
}
}
}

View file

@ -0,0 +1,176 @@
/**
* 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.thinclient.cave.cache.map;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.raytheon.uf.common.dataquery.db.QueryResult;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
/**
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 9, 2011 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
@DynamicSerialize
public class CacheDbMapQuerySerializeable {
@DynamicSerialize
public static class ConstraintAndIndices {
@DynamicSerializeElement
private String constraint;
@DynamicSerializeElement
private List<Integer> indices;
public String getConstraint() {
return constraint;
}
public void setConstraint(String constraint) {
this.constraint = constraint;
}
public List<Integer> getIndices() {
return indices;
}
public void setIndices(List<Integer> indices) {
this.indices = indices;
}
}
@DynamicSerializeElement
private String table;
@DynamicSerializeElement
private String geomField;
@DynamicSerializeElement
private QueryResult data;
@DynamicSerializeElement
private List<ConstraintAndIndices> constraintAndIndices;
@DynamicSerializeElement
private List<String> columnNames;
@DynamicSerializeElement
private String geometryType;;
@DynamicSerializeElement
private List<Double> levels;
public String getTable() {
return table;
}
public void setTable(String table) {
this.table = table;
}
public String getGeomField() {
return geomField;
}
public void setGeomField(String geomField) {
this.geomField = geomField;
}
public QueryResult getData() {
return data;
}
public void setData(QueryResult data) {
this.data = data;
}
public Map<String, List<Integer>> getConstraint2indices() {
Map<String, List<Integer>> m = new HashMap<String, List<Integer>>();
for (ConstraintAndIndices c : constraintAndIndices) {
m.put(c.getConstraint(), c.getIndices());
}
return m;
}
public void setConstraint2indices(
Map<String, List<Integer>> constraint2indices) {
constraintAndIndices = new ArrayList<ConstraintAndIndices>(
constraint2indices.size());
for (Entry<String, List<Integer>> entry : constraint2indices.entrySet()) {
ConstraintAndIndices c = new ConstraintAndIndices();
c.setConstraint(entry.getKey());
c.setIndices(entry.getValue());
constraintAndIndices.add(c);
}
}
public List<ConstraintAndIndices> getConstraintAndIndices() {
return constraintAndIndices;
}
public void setConstraintAndIndices(
List<ConstraintAndIndices> constraintAndIndices) {
this.constraintAndIndices = constraintAndIndices;
}
public List<String> getColumnNames() {
return columnNames;
}
public void setColumnNames(List<String> columnNames) {
this.columnNames = columnNames;
}
public String getGeometryType() {
return geometryType;
}
public void setGeometryType(String geometryType) {
this.geometryType = geometryType;
}
public List<Double> getLevels() {
return levels;
}
public void setLevels(List<Double> levels) {
this.levels = levels;
}
}

View file

@ -60,7 +60,6 @@ import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.map.IMapDescriptor;
import com.raytheon.uf.viz.core.maps.rsc.AbstractDbMapResourceData.ColumnDefinition;
import com.raytheon.uf.viz.core.maps.rsc.MapQueryCache;
import com.raytheon.uf.viz.core.maps.rsc.DbMapResource;
import com.raytheon.uf.viz.core.maps.rsc.DbMapResourceData;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
@ -203,7 +202,7 @@ public class ZoneSelectorResource extends DbMapResource {
// System.out.println(req.query);
// long t0 = System.currentTimeMillis();
QueryResult mappedResult = MapQueryCache
QueryResult mappedResult = DirectDbQuery
.executeMappedQuery(req.query, "maps",
QueryLanguage.SQL);
@ -984,7 +983,6 @@ public class ZoneSelectorResource extends DbMapResource {
return zoneNames;
}
@Override
protected String getGeospatialConstraint(String geometryField, Envelope env) {
StringBuilder constraint = new StringBuilder();