Merge "Issue #1907 and #1908 fixed sampling a attribute dispaly when DataStoreResource is cropped" into development

Former-commit-id: 35f5b04522 [formerly 35f5b04522 [formerly 5188a208a6b66eb024db64efeb8a6409c57d4a64]]
Former-commit-id: fd43f74212
Former-commit-id: 890bb4d832
This commit is contained in:
Ron Anderson 2013-07-29 18:11:30 -05:00 committed by Gerrit Code Review
commit 247372ad8f
3 changed files with 382 additions and 134 deletions

View file

@ -22,6 +22,7 @@ package com.raytheon.uf.viz.gisdatastore.rsc;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -43,7 +44,6 @@ import org.geotools.factory.GeoTools;
import org.geotools.feature.FeatureCollection; import org.geotools.feature.FeatureCollection;
import org.geotools.geometry.GeneralEnvelope; import org.geotools.geometry.GeneralEnvelope;
import org.geotools.geometry.jts.JTS; import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.operation.DefaultMathTransformFactory; import org.geotools.referencing.operation.DefaultMathTransformFactory;
import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.simple.SimpleFeatureType;
@ -56,9 +56,13 @@ import org.opengis.referencing.operation.MathTransform;
import com.raytheon.uf.common.geospatial.MapUtil; import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate; import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.geospatial.util.WorldWrapCorrector; import com.raytheon.uf.common.geospatial.util.WorldWrapCorrector;
import com.raytheon.uf.common.status.IPerformanceStatusHandler;
import com.raytheon.uf.common.status.PerformanceStatus;
import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.time.DataTime; import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.common.time.TimeRange;
import com.raytheon.uf.common.time.util.ITimer;
import com.raytheon.uf.common.time.util.TimeUtil;
import com.raytheon.uf.viz.core.DrawableString; import com.raytheon.uf.viz.core.DrawableString;
import com.raytheon.uf.viz.core.IDisplayPaneContainer; import com.raytheon.uf.viz.core.IDisplayPaneContainer;
import com.raytheon.uf.viz.core.IExtent; import com.raytheon.uf.viz.core.IExtent;
@ -91,6 +95,7 @@ import com.raytheon.viz.ui.input.InputAdapter;
import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LinearRing; import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Point;
@ -106,6 +111,8 @@ import com.vividsolutions.jts.geom.Point;
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Oct 31, 2012 #1326 randerso Initial creation * Oct 31, 2012 #1326 randerso Initial creation
* Feb 22, 2013 #1641 randerso Moved ID_ATTRIBUTE_NAME to package scope * Feb 22, 2013 #1641 randerso Moved ID_ATTRIBUTE_NAME to package scope
* Jul 24, 2013 #1907 randerso Fixed sampling when cropped
* Jul 24, 2013 #1908 randerso Update attributes when cropped
* *
* </pre> * </pre>
* *
@ -116,6 +123,9 @@ import com.vividsolutions.jts.geom.Point;
public class DataStoreResource extends public class DataStoreResource extends
AbstractVizResource<DataStoreResourceData, MapDescriptor> implements AbstractVizResource<DataStoreResourceData, MapDescriptor> implements
IPropertyChangeListener, IResourceDataChanged { IPropertyChangeListener, IResourceDataChanged {
private static final IPerformanceStatusHandler perfLog = PerformanceStatus
.getHandler("GIS:");
static final String ID_ATTRIBUTE_NAME = "Feature.ID"; static final String ID_ATTRIBUTE_NAME = "Feature.ID";
private static final int CLICK_TOLERANCE = 3; private static final int CLICK_TOLERANCE = 3;
@ -129,20 +139,28 @@ public class DataStoreResource extends
*/ */
private static final double RECENTER_TOLERANCE = 0.8; private static final double RECENTER_TOLERANCE = 0.8;
/** Property Key for highlight color */
public static final String HIGHLIGHT_COLOR_KEY = "HighlightColor"; public static final String HIGHLIGHT_COLOR_KEY = "HighlightColor";
/** Default value for highlight color */
public static final String HIGHLIGHT_COLOR_DEFAULT = "HotPink"; public static final String HIGHLIGHT_COLOR_DEFAULT = "HotPink";
/** Property Key for highlight style */
public static final String HIGHLIGHT_STYLE_KEY = "HighlightStyle"; public static final String HIGHLIGHT_STYLE_KEY = "HighlightStyle";
/** Default value for highlight style */
public static final String HIGHLIGHT_STYLE_DEFAULT = "SOLID"; public static final String HIGHLIGHT_STYLE_DEFAULT = "SOLID";
/** Property Key for highlight width */
public static final String HIGHLIGHT_WIDTH_KEY = "HighlightWidth"; public static final String HIGHLIGHT_WIDTH_KEY = "HighlightWidth";
/** Default value for highlight width */
public static final String HIGHLIGHT_WIDTH_DEFAULT = "2"; public static final String HIGHLIGHT_WIDTH_DEFAULT = "2";
/** Property Key for product opacity */
public static final String PRODUCT_OPACITY_KEY = "ProductOpacity"; public static final String PRODUCT_OPACITY_KEY = "ProductOpacity";
/** Default value for product opacity */
public static final String PRODUCT_OPACITY_DEFAULT = "0.35"; public static final String PRODUCT_OPACITY_DEFAULT = "0.35";
protected static final double EXPANSION_FACTOR = 0.25; protected static final double EXPANSION_FACTOR = 0.25;
@ -296,7 +314,7 @@ public class DataStoreResource extends
@Override @Override
public boolean handleMouseDownMove(int x, int y, int mouseButton) { public boolean handleMouseDownMove(int x, int y, int mouseButton) {
if (rubberBandExtent != null) { if (rubberBandExtent != null) {
if (mouseButton == 1 && inDrag) { if ((mouseButton == 1) && inDrag) {
IDisplayPaneContainer container = getResourceContainer(); IDisplayPaneContainer container = getResourceContainer();
Coordinate c = container.translateClick(x, y); Coordinate c = container.translateClick(x, y);
if (c != null) { if (c != null) {
@ -319,7 +337,7 @@ public class DataStoreResource extends
@Override @Override
public boolean handleMouseUp(int x, int y, int mouseButton) { public boolean handleMouseUp(int x, int y, int mouseButton) {
if (rubberBandExtent != null) { if (rubberBandExtent != null) {
if (mouseButton == 1 && inDrag) { if ((mouseButton == 1) && inDrag) {
IDisplayPaneContainer container = getResourceContainer(); IDisplayPaneContainer container = getResourceContainer();
Coordinate c = container.translateClick(x, y); Coordinate c = container.translateClick(x, y);
if (c != null) { if (c != null) {
@ -368,14 +386,42 @@ public class DataStoreResource extends
} }
} }
/**
* Interface for listeners to be notified of rubber band selection changes
*/
public static interface IRubberBandSelectionListener { public static interface IRubberBandSelectionListener {
/**
* Called when rubber band selection changes
*
* @param extent
* selected pixel extent
*/
public void rubberBandSelectionChanged(PixelExtent extent); public void rubberBandSelectionChanged(PixelExtent extent);
} }
/**
* Interface for listeners to be notified of double click selection
*/
public static interface IDoubleClickSelectionListener { public static interface IDoubleClickSelectionListener {
/**
* Called when double click selection occurs
*
* @param selectedIds
* IDs of selected features
*/
public void selectedFeaturesChanged(List<String> selectedIds); public void selectedFeaturesChanged(List<String> selectedIds);
} }
/**
* Interface for listeners to be notified when attributes are updated
*/
public static interface IAttributesUpdatedListener {
/**
* Called when attributes are updated
*/
public void attributesUpdated();
}
protected DataStore dataStore; protected DataStore dataStore;
private String typeName; private String typeName;
@ -438,12 +484,23 @@ public class DataStoreResource extends
private ListenerList doubleClickListeners; private ListenerList doubleClickListeners;
private ListenerList attributesUpdatedListeners;
private Coordinate dragPromptCoord; private Coordinate dragPromptCoord;
private WorldWrapCorrector worldWrapCorrector; private WorldWrapCorrector worldWrapCorrector;
private String sampleAttribute; private String sampleAttribute;
private Geometry boundingGeom;
/**
* Constructor for DataStoreResource
*
* @param data
* @param loadProperties
* @throws IOException
*/
public DataStoreResource(DataStoreResourceData data, public DataStoreResource(DataStoreResourceData data,
LoadProperties loadProperties) throws IOException { LoadProperties loadProperties) throws IOException {
super(data, loadProperties); super(data, loadProperties);
@ -454,6 +511,7 @@ public class DataStoreResource extends
this.displayName = data.getMapName(); this.displayName = data.getMapName();
this.rubberBandListeners = new ListenerList(); this.rubberBandListeners = new ListenerList();
this.doubleClickListeners = new ListenerList(); this.doubleClickListeners = new ListenerList();
this.attributesUpdatedListeners = new ListenerList();
GeneralEnvelope env = new GeneralEnvelope(MapUtil.LATLON_PROJECTION); GeneralEnvelope env = new GeneralEnvelope(MapUtil.LATLON_PROJECTION);
env.setEnvelope(-180.0, -90.0, 180.0, 90.0); env.setEnvelope(-180.0, -90.0, 180.0, 90.0);
@ -500,10 +558,7 @@ public class DataStoreResource extends
@Override @Override
protected void initInternal(IGraphicsTarget target) throws VizException { protected void initInternal(IGraphicsTarget target) throws VizException {
long t0 = System.currentTimeMillis();
loadDataStore(); loadDataStore();
System.out.println("loadDataStore took "
+ (System.currentTimeMillis() - t0) + " ms");
getCapability(LabelableCapability.class).setAvailableLabelFields( getCapability(LabelableCapability.class).setAvailableLabelFields(
this.attributeNames); this.attributeNames);
@ -533,6 +588,9 @@ public class DataStoreResource extends
protected void loadDataStore() throws VizException { protected void loadDataStore() throws VizException {
try { try {
ITimer timer = TimeUtil.getTimer();
timer.start();
schema = dataStore.getSchema(typeName); schema = dataStore.getSchema(typeName);
List<AttributeDescriptor> attrDesc = schema List<AttributeDescriptor> attrDesc = schema
.getAttributeDescriptors(); .getAttributeDescriptors();
@ -557,12 +615,16 @@ public class DataStoreResource extends
displayAttributes = new HashMap<String, DataStoreResource.DisplayAttributes>( displayAttributes = new HashMap<String, DataStoreResource.DisplayAttributes>(
(int) Math.ceil(attributeNames.length / 0.75f), 0.75f); (int) Math.ceil(attributeNames.length / 0.75f), 0.75f);
timer.stop();
perfLog.logDuration("loadDataStore", timer.getElapsedTime());
} catch (Exception e) { } catch (Exception e) {
throw new VizException("Error loading shapefile: ", e); throw new VizException("Error loading shapefile: ", e);
} }
} }
private void loadAttributes(Envelope envelope) { private void loadAttributes() {
ITimer timer = TimeUtil.getTimer();
timer.start();
DefaultQuery query = new DefaultQuery(); DefaultQuery query = new DefaultQuery();
query.setTypeName(typeName); query.setTypeName(typeName);
@ -571,11 +633,25 @@ public class DataStoreResource extends
String geomField = schema.getGeometryDescriptor().getLocalName(); String geomField = schema.getGeometryDescriptor().getLocalName();
ReferencedEnvelope bbox = new ReferencedEnvelope(envelope, IExtent worldExtent = getDescriptor().getRenderableDisplay().getView()
MapUtil.LATLON_PROJECTION); .getExtent();
Filter bboxFilter = ff.bbox(ff.property(geomField), bbox); Rectangle screenBounds = getResourceContainer().getActiveDisplayPane()
.getBounds();
double worldToScreenRatio = worldExtent.getWidth() / screenBounds.width;
query.setFilter(bboxFilter); List<Geometry> geomList = new ArrayList<Geometry>();
PixelExtent extent = clipToProjExtent(projExtent);
Geometry boundingGeom = buildBoundingGeometry(extent,
worldToScreenRatio);
flattenGeometry(boundingGeom, geomList);
List<Filter> filterList = new ArrayList<Filter>(geomList.size());
for (Geometry g : geomList) {
Filter filter = ff
.intersects(ff.property(geomField), ff.literal(g));
filterList.add(filter);
}
query.setFilter(ff.or(filterList));
FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection = null; FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection = null;
Iterator<SimpleFeature> featureIterator = null; Iterator<SimpleFeature> featureIterator = null;
@ -612,21 +688,19 @@ public class DataStoreResource extends
featureCollection.close(featureIterator); featureCollection.close(featureIterator);
} }
} }
timer.stop();
perfLog.logDuration("loadAttributes", timer.getElapsedTime());
} }
private Envelope buildEnvelope(PixelExtent extent) throws VizException { private void flattenGeometry(Geometry geometry, List<Geometry> geomList) {
Envelope env = null; if (geometry instanceof GeometryCollection) {
try { GeometryCollection collection = (GeometryCollection) geometry;
Envelope e = descriptor.pixelToWorld(extent, descriptor.getCRS()); for (int i = 0; i < collection.getNumGeometries(); i++) {
flattenGeometry(collection.getGeometryN(i), geomList);
ReferencedEnvelope ref = new ReferencedEnvelope(e, }
descriptor.getCRS()); } else {
env = ref.transform(MapUtil.LATLON_PROJECTION, true); geomList.add(geometry);
} catch (Exception e) {
throw new VizException("Error transforming extent", e);
} }
return env;
} }
private Geometry buildBoundingGeometry(PixelExtent extent, private Geometry buildBoundingGeometry(PixelExtent extent,
@ -638,9 +712,9 @@ public class DataStoreResource extends
new double[] { 0, -90 }); new double[] { 0, -90 });
double[] p = null; double[] p = null;
if (northPole != null && extent.contains(northPole)) { if ((northPole != null) && extent.contains(northPole)) {
p = northPole; p = northPole;
} else if (southPole != null && extent.contains(southPole)) { } else if ((southPole != null) && extent.contains(southPole)) {
p = southPole; p = southPole;
} }
@ -664,7 +738,7 @@ public class DataStoreResource extends
List<Geometry> geometries = new ArrayList<Geometry>(4); List<Geometry> geometries = new ArrayList<Geometry>(4);
for (PixelExtent ext : quadrant) { for (PixelExtent ext : quadrant) {
if (ext.getWidth() > 0 && ext.getHeight() > 0) { if ((ext.getWidth() > 0) && (ext.getHeight() > 0)) {
geometries.add(geometryFromExtent(ext, worldToScreenRatio)); geometries.add(geometryFromExtent(ext, worldToScreenRatio));
} }
} }
@ -703,22 +777,22 @@ public class DataStoreResource extends
double dx = extent.getWidth() / nx; double dx = extent.getWidth() / nx;
double dy = extent.getHeight() / ny; double dy = extent.getHeight() / ny;
Coordinate[] coordinates = new Coordinate[2 * (nx + ny) + 1]; Coordinate[] coordinates = new Coordinate[(2 * (nx + ny)) + 1];
int i = 0; int i = 0;
for (int x = 0; x < nx; x++) { for (int x = 0; x < nx; x++) {
coordinates[i++] = new Coordinate(x * dx + extent.getMinX(), coordinates[i++] = new Coordinate((x * dx) + extent.getMinX(),
extent.getMinY()); extent.getMinY());
} }
for (int y = 0; y < ny; y++) { for (int y = 0; y < ny; y++) {
coordinates[i++] = new Coordinate(extent.getMaxX(), y * dy coordinates[i++] = new Coordinate(extent.getMaxX(), (y * dy)
+ extent.getMinY()); + extent.getMinY());
} }
for (int x = nx; x > 0; x--) { for (int x = nx; x > 0; x--) {
coordinates[i++] = new Coordinate(x * dx + extent.getMinX(), coordinates[i++] = new Coordinate((x * dx) + extent.getMinX(),
extent.getMaxY()); extent.getMaxY());
} }
for (int y = ny; y > 0; y--) { for (int y = ny; y > 0; y--) {
coordinates[i++] = new Coordinate(extent.getMinX(), y * dy coordinates[i++] = new Coordinate(extent.getMinX(), (y * dy)
+ extent.getMinY()); + extent.getMinY());
} }
coordinates[i++] = coordinates[0]; coordinates[i++] = coordinates[0];
@ -737,7 +811,7 @@ public class DataStoreResource extends
// determine if we should display in this frame // determine if we should display in this frame
DataTime curTime = paintProps.getFramesInfo().getCurrentFrame(); DataTime curTime = paintProps.getFramesInfo().getCurrentFrame();
if (curTime != null && timeRange != null) { if ((curTime != null) && (timeRange != null)) {
if (timeRange.isValid()) { // non-zero duration if (timeRange.isValid()) { // non-zero duration
if (!timeRange.contains(curTime.getValidTime().getTime())) { if (!timeRange.contains(curTime.getValidTime().getTime())) {
return; return;
@ -759,7 +833,7 @@ public class DataStoreResource extends
String shadingField = getCapability(ShadeableCapability.class) String shadingField = getCapability(ShadeableCapability.class)
.getShadingField(); .getShadingField();
boolean isShaded = isPolygonal() && shadingField != null; boolean isShaded = isPolygonal() && (shadingField != null);
boolean isProduct = this.timeRange != null; boolean isProduct = this.timeRange != null;
boolean updateLabels = isLabeled && !labelField.equals(lastLabelField); boolean updateLabels = isLabeled && !labelField.equals(lastLabelField);
@ -771,15 +845,14 @@ public class DataStoreResource extends
updateShading = !shadingField.equals(lastShadingField); updateShading = !shadingField.equals(lastShadingField);
} }
} }
boolean updateExtent = lastExtent == null boolean updateExtent = (lastExtent == null)
|| !lastExtent.getEnvelope().contains( || !lastExtent.getEnvelope().contains(
clipToProjExtent(screenExtent).getEnvelope()); clipToProjExtent(screenExtent).getEnvelope());
if (updateHighlights || updateLabels || updateShading || updateExtent) { if (updateHighlights || updateLabels || updateShading || updateExtent) {
if (!paintProps.isZooming()) { if (!paintProps.isZooming()) {
PixelExtent expandedExtent = getExpandedExtent(screenExtent); PixelExtent expandedExtent = getExpandedExtent(screenExtent);
// Envelope env = buildEnvelope(expandedExtent); boundingGeom = buildBoundingGeometry(expandedExtent,
Geometry boundingGeom = buildBoundingGeometry(expandedExtent,
worldToScreenRatio); worldToScreenRatio);
String geomField = schema.getGeometryDescriptor() String geomField = schema.getGeometryDescriptor()
@ -804,26 +877,26 @@ public class DataStoreResource extends
float alpha = paintProps.getAlpha(); float alpha = paintProps.getAlpha();
if ((isProduct || isShaded) && shadedShape != null if ((isProduct || isShaded) && (shadedShape != null)
&& shadedShape.isDrawable()) { && shadedShape.isDrawable()) {
float opacity = getCapability(ShadeableCapability.class) float opacity = getCapability(ShadeableCapability.class)
.getOpacity(); .getOpacity();
aTarget.drawShadedShape(shadedShape, alpha * opacity); aTarget.drawShadedShape(shadedShape, alpha * opacity);
} }
if (outlineShape != null && outlineShape.isDrawable() if ((outlineShape != null) && outlineShape.isDrawable()
&& getCapability(OutlineCapability.class).isOutlineOn()) { && getCapability(OutlineCapability.class).isOutlineOn()) {
aTarget.drawWireframeShape(outlineShape, aTarget.drawWireframeShape(outlineShape,
getCapability(ColorableCapability.class).getColor(), getCapability(ColorableCapability.class).getColor(),
getCapability(OutlineCapability.class).getOutlineWidth(), getCapability(OutlineCapability.class).getOutlineWidth(),
getCapability(OutlineCapability.class).getLineStyle(), getCapability(OutlineCapability.class).getLineStyle(),
alpha); alpha);
} else if (outlineShape == null } else if ((outlineShape == null)
&& getCapability(OutlineCapability.class).isOutlineOn()) { && getCapability(OutlineCapability.class).isOutlineOn()) {
issueRefresh(); issueRefresh();
} }
if (highlightShape != null && highlightShape.isDrawable() if ((highlightShape != null) && highlightShape.isDrawable()
&& getCapability(OutlineCapability.class).isOutlineOn()) { && getCapability(OutlineCapability.class).isOutlineOn()) {
aTarget.drawWireframeShape(highlightShape, highlightColor, aTarget.drawWireframeShape(highlightShape, highlightColor,
highlightWidth, highlightStyle); highlightWidth, highlightStyle);
@ -832,7 +905,7 @@ public class DataStoreResource extends
double labelMagnification = getCapability(MagnificationCapability.class) double labelMagnification = getCapability(MagnificationCapability.class)
.getMagnification(); .getMagnification();
if (labels != null && isLabeled && labelMagnification != 0) { if ((labels != null) && isLabeled && (labelMagnification != 0)) {
drawLabels(aTarget, paintProps, labelMagnification, drawLabels(aTarget, paintProps, labelMagnification,
worldToScreenRatio); worldToScreenRatio);
} }
@ -906,7 +979,7 @@ public class DataStoreResource extends
.getDensity(); .getDensity();
double minScreenDistance = Double.MAX_VALUE; double minScreenDistance = Double.MAX_VALUE;
if (density > 0) { if (density > 0) {
minScreenDistance = worldToScreenRatio * BASE_DENSITY_MULT minScreenDistance = (worldToScreenRatio * BASE_DENSITY_MULT)
/ density; / density;
} }
@ -937,7 +1010,7 @@ public class DataStoreResource extends
node.location[1] node.location[1]
+ ((node.rect.getHeight() - node.rect.getY()) * worldToScreenRatio)); + ((node.rect.getHeight() - node.rect.getY()) * worldToScreenRatio));
if (lastLabel != null && lastLabel.equals(node.label)) { if ((lastLabel != null) && lastLabel.equals(node.label)) {
// check intersection of extents // check intersection of extents
for (IExtent ext : extents) { for (IExtent ext : extents) {
if (ext.intersects(strExtent)) { if (ext.intersects(strExtent)) {
@ -1114,7 +1187,9 @@ public class DataStoreResource extends
// sampling is only supported when loaded as product // sampling is only supported when loaded as product
if (timeRange != null) { if (timeRange != null) {
if (sampleAttribute != null) { if (sampleAttribute != null) {
// TODO get the query off the UI thread
List<SimpleFeature> features = findFeatures(coord); List<SimpleFeature> features = findFeatures(coord);
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (SimpleFeature f : features) { for (SimpleFeature f : features) {
Object attr; Object attr;
@ -1136,32 +1211,32 @@ public class DataStoreResource extends
return sampleString; return sampleString;
} }
/**
* Set the displayed resource name
*
* @param name
*/
public void setName(String name) { public void setName(String name) {
if (name != null && name.isEmpty()) { if ((name != null) && name.isEmpty()) {
name = null; name = null;
} }
this.displayName = name; this.displayName = name;
this.resourceData.setMapName(name); this.resourceData.setMapName(name);
} }
/**
* @return the attribute names
*/
public String[] getAttributeNames() { public String[] getAttributeNames() {
return attributeNames; return attributeNames;
} }
/**
* @return the attributes
*/
public Object[][] getAttributes() { public Object[][] getAttributes() {
if (attributes == null) { if (attributes == null) {
try { loadAttributes();
// TODO need to fix this so it doesn't load features that are
// outside fully zoomed out window
Envelope env = buildEnvelope(projExtent);
long t0 = System.currentTimeMillis();
loadAttributes(env);
System.out.println("loadAttributes took "
+ (System.currentTimeMillis() - t0) + " ms");
} catch (VizException e) {
Activator.statusHandler.handle(Priority.PROBLEM,
e.getLocalizedMessage(), e);
}
} }
return attributes; return attributes;
} }
@ -1178,17 +1253,15 @@ public class DataStoreResource extends
return schema; return schema;
} }
/**
* @param coord
* @return
* @throws VizException
*/
private List<SimpleFeature> findFeatures(ReferencedCoordinate coord) private List<SimpleFeature> findFeatures(ReferencedCoordinate coord)
throws VizException { throws VizException {
// ITimer timer = TimeUtil.getTimer();
List<SimpleFeature> features = new ArrayList<SimpleFeature>(); // timer.start();
Coordinate pix;
try {
pix = coord.asPixel(getDescriptor().getGridGeometry());
} catch (Exception e) {
throw new VizException(
"Error transforming sample point to lat/lon ", e);
}
DefaultQuery query = new DefaultQuery(); DefaultQuery query = new DefaultQuery();
query.setTypeName(typeName); query.setTypeName(typeName);
@ -1198,48 +1271,79 @@ public class DataStoreResource extends
String geomField = schema.getGeometryDescriptor().getLocalName(); String geomField = schema.getGeometryDescriptor().getLocalName();
IExtent worldExtent = getDescriptor().getRenderableDisplay().getView() boolean polygonal = isPolygonal();
.getExtent(); Filter clickFilter;
Rectangle screenBounds = getResourceContainer().getActiveDisplayPane() try {
.getBounds(); if (polygonal) {
double worldToScreenRatio = worldExtent.getWidth() / screenBounds.width; GeometryFactory gf = new GeometryFactory();
Point clickPoint = gf.createPoint(coord.asLatLon());
clickFilter = ff.contains(ff.property(geomField),
ff.literal(clickPoint));
} else {
Coordinate pix;
pix = coord.asPixel(getDescriptor().getGridGeometry());
double delta = CLICK_TOLERANCE * worldToScreenRatio; IExtent worldExtent = getDescriptor().getRenderableDisplay()
PixelExtent bboxExtent = new PixelExtent(pix.x - delta, pix.x + delta, .getView().getExtent();
pix.y - delta, pix.y + delta); Rectangle screenBounds = getResourceContainer()
Geometry boundingGeom = buildBoundingGeometry(bboxExtent, .getActiveDisplayPane().getBounds();
worldToScreenRatio); double worldToScreenRatio = worldExtent.getWidth()
/ screenBounds.width;
List<Filter> filterList = new ArrayList<Filter>( double delta = CLICK_TOLERANCE * worldToScreenRatio;
boundingGeom.getNumGeometries()); PixelExtent bboxExtent = new PixelExtent(pix.x - delta, pix.x
for (int i = 0; i < boundingGeom.getNumGeometries(); i++) { + delta, pix.y - delta, pix.y + delta);
Filter filter = ff.intersects(ff.property(geomField), Geometry clickBox = buildBoundingGeometry(bboxExtent,
ff.literal(boundingGeom.getGeometryN(i))); worldToScreenRatio);
filterList.add(filter); List<Geometry> clickGeomList = new ArrayList<Geometry>();
flattenGeometry(clickBox, clickGeomList);
List<Filter> clickFilterList = new ArrayList<Filter>(
clickGeomList.size());
for (Geometry g : clickGeomList) {
Filter filter = ff.intersects(ff.property(geomField),
ff.literal(g));
clickFilterList.add(filter);
}
clickFilter = ff.or(clickFilterList);
}
} catch (Exception e) {
throw new VizException(
"Error transforming sample point to lat/lon ", e);
} }
query.setFilter(ff.or(filterList));
// query.setFilter(ff.and(clickFilter, boundingFilter));
query.setFilter(clickFilter);
FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection = null; FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection = null;
Iterator<SimpleFeature> featureIterator = null; Iterator<SimpleFeature> featureIterator = null;
List<SimpleFeature> features;
try { try {
FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = dataStore FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = dataStore
.getFeatureSource(typeName); .getFeatureSource(typeName);
featureCollection = featureSource.getFeatures(query); featureCollection = featureSource.getFeatures(query);
int size = featureCollection.size(); features = new ArrayList<SimpleFeature>(featureCollection.size());
featureIterator = featureCollection.iterator(); featureIterator = featureCollection.iterator();
while (featureIterator.hasNext()) { while (featureIterator.hasNext()) {
features.add(featureIterator.next()); SimpleFeature f = featureIterator.next();
Geometry g = (Geometry) f.getDefaultGeometry();
if (g.intersects(boundingGeom)) {
features.add(f);
}
} }
} catch (Exception e) { } catch (Exception e) {
Activator.statusHandler.handle(Priority.PROBLEM, Activator.statusHandler.handle(Priority.PROBLEM,
e.getLocalizedMessage(), e); e.getLocalizedMessage(), e);
features = Collections.emptyList();
} finally { } finally {
if (featureIterator != null) { if (featureIterator != null) {
featureCollection.close(featureIterator); featureCollection.close(featureIterator);
} }
} }
// timer.stop();
// perfLog.logDuration("findFeatures", timer.getElapsedTime());
return features; return features;
} }
@ -1252,6 +1356,14 @@ public class DataStoreResource extends
return da; return da;
} }
/**
* Make a feature visible/invisible
*
* @param id
* ID of feature to change
* @param visible
* true for visible, false for invisible
*/
public void setVisible(String id, boolean visible) { public void setVisible(String id, boolean visible) {
DisplayAttributes da = getDisplayAttributes(id); DisplayAttributes da = getDisplayAttributes(id);
da.setVisible(visible); da.setVisible(visible);
@ -1259,11 +1371,26 @@ public class DataStoreResource extends
issueRefresh(); issueRefresh();
} }
public boolean getVisible(String id) { /**
* Determine if a feature is visibile
*
* @param id
* ID of feature in question
* @return true if visible, false if invisible
*/
public boolean isVisible(String id) {
DisplayAttributes da = getDisplayAttributes(id); DisplayAttributes da = getDisplayAttributes(id);
return da.isVisible(); return da.isVisible();
} }
/**
* Highlight/Unhighlight a feature
*
* @param id
* ID of feature to change
* @param highlighted
* true for highlighted, false for unhighlighted
*/
public void setHighlighted(String id, boolean highlighted) { public void setHighlighted(String id, boolean highlighted) {
DisplayAttributes da = getDisplayAttributes(id); DisplayAttributes da = getDisplayAttributes(id);
da.setHighlighted(highlighted); da.setHighlighted(highlighted);
@ -1272,11 +1399,24 @@ public class DataStoreResource extends
issueRefresh(); issueRefresh();
} }
public boolean getHighlighted(String id) { /**
* Determine if a feature is highlighted
*
* @param id
* ID of feature in question
* @return true if highlighted, false if unhighlighted
*/
public boolean isHighlighted(String id) {
DisplayAttributes da = getDisplayAttributes(id); DisplayAttributes da = getDisplayAttributes(id);
return da.isHighlighted(); return da.isHighlighted();
} }
/**
* Recenter the display on a feature if it is off screen
*
* @param id
* ID of feature to be recentered about
*/
public void recenter(String id) { public void recenter(String id) {
DisplayAttributes da = getDisplayAttributes(id); DisplayAttributes da = getDisplayAttributes(id);
Point p = da.getCentroid(); Point p = da.getCentroid();
@ -1323,10 +1463,21 @@ public class DataStoreResource extends
} }
} }
/**
* Activate rubber band selection box
*/
public void activateRubberBandBox() { public void activateRubberBandBox() {
rubberBandExtent = new PixelExtent(0, 0, 0, 0); rubberBandExtent = new PixelExtent(0, 0, 0, 0);
} }
/**
* Update rubber band selection
*
* @param start
* starting corner of selection
* @param end
* ending corner of selection
*/
public void updateRubberBandBox(Coordinate start, Coordinate end) { public void updateRubberBandBox(Coordinate start, Coordinate end) {
dragPromptCoord = end; dragPromptCoord = end;
double minX = Math.min(start.x, end.x); double minX = Math.min(start.x, end.x);
@ -1337,8 +1488,12 @@ public class DataStoreResource extends
issueRefresh(); issueRefresh();
} }
/**
* Deactivate rubber band selection box
*/
public void deactivateRubberBandBox() { public void deactivateRubberBandBox() {
if (rubberBandExtent.getWidth() > 0 && rubberBandExtent.getHeight() > 0) { if ((rubberBandExtent.getWidth() > 0)
&& (rubberBandExtent.getHeight() > 0)) {
for (Object obj : rubberBandListeners.getListeners()) { for (Object obj : rubberBandListeners.getListeners()) {
IRubberBandSelectionListener listener = (IRubberBandSelectionListener) obj; IRubberBandSelectionListener listener = (IRubberBandSelectionListener) obj;
listener.rubberBandSelectionChanged(rubberBandExtent); listener.rubberBandSelectionChanged(rubberBandExtent);
@ -1350,43 +1505,111 @@ public class DataStoreResource extends
issueRefresh(); issueRefresh();
} }
/**
* Add a rubber band selection listener
*
* @param listener
*/
public void addRubberBandSelectionListener( public void addRubberBandSelectionListener(
IRubberBandSelectionListener listener) { IRubberBandSelectionListener listener) {
rubberBandListeners.add(listener); rubberBandListeners.add(listener);
} }
/**
* Remove a rubber band selection listener
*
* @param listener
*/
public void removeRubberBandSelectionListener( public void removeRubberBandSelectionListener(
IRubberBandSelectionListener listener) { IRubberBandSelectionListener listener) {
rubberBandListeners.remove(listener); rubberBandListeners.remove(listener);
} }
/**
* Add a double click selection listener
*
* @param listener
*/
public void addDoubleClickSelectionListener( public void addDoubleClickSelectionListener(
IDoubleClickSelectionListener listener) { IDoubleClickSelectionListener listener) {
doubleClickListeners.add(listener); doubleClickListeners.add(listener);
} }
/**
* Remove a double click selection listener
*
* @param listener
*/
public void removeDoubleClickSelectionListener( public void removeDoubleClickSelectionListener(
IDoubleClickSelectionListener listener) { IDoubleClickSelectionListener listener) {
doubleClickListeners.remove(listener); doubleClickListeners.remove(listener);
} }
/**
* Add an attributes updated listener
*
* @param listener
*/
public void addAttributesUpdatedListener(IAttributesUpdatedListener listener) {
attributesUpdatedListeners.add(listener);
}
/**
* Remove an attributes updated listener
*
* @param listener
*/
public void removeAttributesUpdatedListener(
IAttributesUpdatedListener listener) {
attributesUpdatedListeners.remove(listener);
}
private void notifyAttributesUpdatedListeners() {
for (Object listener : attributesUpdatedListeners.getListeners()) {
((IAttributesUpdatedListener) listener).attributesUpdated();
}
}
/**
* Crop the displayed features to the selected extent
*
* @param extent
* the selected extent
*/
public void crop(PixelExtent extent) { public void crop(PixelExtent extent) {
cropExtent = extent; cropExtent = extent;
lastExtent = null; lastExtent = null;
attributes = null;
issueRefresh(); issueRefresh();
notifyAttributesUpdatedListeners();
} }
/**
* Determine if the resource is cropped
*
* @return true if cropped
*/
public boolean isCropped() { public boolean isCropped() {
return cropExtent != null; return cropExtent != null;
} }
/**
* Uncrop the resource (display all features)
*/
public void uncrop() { public void uncrop() {
cropExtent = null; cropExtent = null;
lastExtent = null; lastExtent = null;
attributes = null;
issueRefresh(); issueRefresh();
notifyAttributesUpdatedListeners();
} }
/**
* Set the time range associated with the resource when displayed as a
* product
*
* @param timeRange
*/
public void setTimeRange(TimeRange timeRange) { public void setTimeRange(TimeRange timeRange) {
this.timeRange = timeRange; this.timeRange = timeRange;
} }
@ -1409,10 +1632,20 @@ public class DataStoreResource extends
issueRefresh(); issueRefresh();
} }
/**
* Get the name of the sample attribute
*
* @return sample attribute name
*/
public String getSampleAttribute() { public String getSampleAttribute() {
return sampleAttribute; return sampleAttribute;
} }
/**
* Set the sample attribute name
*
* @param sampleAttribute
*/
public void setSampleAttribute(String sampleAttribute) { public void setSampleAttribute(String sampleAttribute) {
this.sampleAttribute = sampleAttribute; this.sampleAttribute = sampleAttribute;
} }

View file

@ -55,6 +55,7 @@ import com.vividsolutions.jts.geom.Point;
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Oct 31, 2012 #1326 randerso Initial creation * Oct 31, 2012 #1326 randerso Initial creation
* Feb 22, 2013 #1641 randerso Added checks for using ID as label or shading attribute * Feb 22, 2013 #1641 randerso Added checks for using ID as label or shading attribute
* Jul 24, 2014 #1908 randerso Removed debug sysouts
* *
* </pre> * </pre>
* *
@ -201,14 +202,14 @@ class ReloadJob extends Job {
pendingRequest = null; pendingRequest = null;
} }
while (req != null) { while (req != null) {
System.out.println("Processing request: " + req.number); // System.out.println("Processing request: " + req.number);
Result result = new Result(); Result result = new Result();
FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection = null; FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection = null;
Iterator<SimpleFeature> featureIterator = null; Iterator<SimpleFeature> featureIterator = null;
try { try {
if (pendingRequest != null) { if (pendingRequest != null) {
System.out.println("Canceling request: " + req.number); // System.out.println("Canceling request: " + req.number);
result.dispose(); result.dispose();
result = null; result = null;
return Status.CANCEL_STATUS; return Status.CANCEL_STATUS;
@ -216,13 +217,13 @@ class ReloadJob extends Job {
List<String> fields = new ArrayList<String>(); List<String> fields = new ArrayList<String>();
fields.add(req.geomField); fields.add(req.geomField);
if (req.labelField != null if ((req.labelField != null)
&& !fields.contains(req.labelField) && !fields.contains(req.labelField)
&& !req.labelField && !req.labelField
.equals(DataStoreResource.ID_ATTRIBUTE_NAME)) { .equals(DataStoreResource.ID_ATTRIBUTE_NAME)) {
fields.add(req.labelField); fields.add(req.labelField);
} }
if (req.shadingField != null if ((req.shadingField != null)
&& !fields.contains(req.shadingField) && !fields.contains(req.shadingField)
&& !req.shadingField && !req.shadingField
.equals(DataStoreResource.ID_ATTRIBUTE_NAME)) { .equals(DataStoreResource.ID_ATTRIBUTE_NAME)) {
@ -238,7 +239,7 @@ class ReloadJob extends Job {
List<LabelNode> newLabels = new ArrayList<LabelNode>(); List<LabelNode> newLabels = new ArrayList<LabelNode>();
IShadedShape newShadedShape = null; IShadedShape newShadedShape = null;
if (req.isProduct || req.shadingField != null) { if (req.isProduct || (req.shadingField != null)) {
newShadedShape = req.target.createShadedShape(false, newShadedShape = req.target.createShadedShape(false,
req.rsc.getDescriptor().getGridGeometry(), true); req.rsc.getDescriptor().getGridGeometry(), true);
} }
@ -297,7 +298,8 @@ class ReloadJob extends Job {
int numPoints = 0; int numPoints = 0;
while (featureIterator.hasNext()) { while (featureIterator.hasNext()) {
if (pendingRequest != null) { if (pendingRequest != null) {
System.out.println("Canceling request: " + req.number); // System.out.println("Canceling request: " +
// req.number);
result.dispose(); result.dispose();
result = null; result = null;
return Status.CANCEL_STATUS; return Status.CANCEL_STATUS;
@ -340,7 +342,7 @@ class ReloadJob extends Job {
shadingAttr = id; shadingAttr = id;
} }
if (labelAttr != null && g != null) { if ((labelAttr != null) && (g != null)) {
String label; String label;
if (labelAttr instanceof BigDecimal) { if (labelAttr instanceof BigDecimal) {
label = Double.toString(((Number) labelAttr) label = Double.toString(((Number) labelAttr)
@ -402,7 +404,8 @@ class ReloadJob extends Job {
ColorableCapability.class).getColor(); ColorableCapability.class).getColor();
for (Geometry g : resultingGeoms) { for (Geometry g : resultingGeoms) {
if (pendingRequest != null) { if (pendingRequest != null) {
System.out.println("Canceling request: " + req.number); // System.out.println("Canceling request: " +
// req.number);
result.dispose(); result.dispose();
result = null; result = null;
return Status.CANCEL_STATUS; return Status.CANCEL_STATUS;
@ -426,13 +429,14 @@ class ReloadJob extends Job {
newOutlineShape.compile(); newOutlineShape.compile();
if (req.isProduct || req.shadingField != null) { if (req.isProduct || (req.shadingField != null)) {
newShadedShape.compile(); newShadedShape.compile();
} }
for (Geometry g : highlightGeoms) { for (Geometry g : highlightGeoms) {
if (pendingRequest != null) { if (pendingRequest != null) {
System.out.println("Canceling request: " + req.number); // System.out.println("Canceling request: " +
// req.number);
result.dispose(); result.dispose();
result = null; result = null;
return Status.CANCEL_STATUS; return Status.CANCEL_STATUS;
@ -465,7 +469,7 @@ class ReloadJob extends Job {
featureCollection.close(featureIterator); featureCollection.close(featureIterator);
} }
if (result != null) { if (result != null) {
System.out.println("Completed request: " + req.number); // System.out.println("Completed request: " + req.number);
if (resultQueue.size() == QUEUE_LIMIT) { if (resultQueue.size() == QUEUE_LIMIT) {
resultQueue.poll(); resultQueue.poll();
} }

View file

@ -65,6 +65,7 @@ import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource; import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.ResourceList.RemoveListener; import com.raytheon.uf.viz.core.rsc.ResourceList.RemoveListener;
import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource; import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource;
import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource.IAttributesUpdatedListener;
import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource.IDoubleClickSelectionListener; import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource.IDoubleClickSelectionListener;
import com.raytheon.viz.ui.dialogs.CaveJFACEDialog; import com.raytheon.viz.ui.dialogs.CaveJFACEDialog;
import com.raytheon.viz.ui.dialogs.ICloseCallback; import com.raytheon.viz.ui.dialogs.ICloseCallback;
@ -80,6 +81,8 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Oct 30, 2012 #1326 randerso Initial creation * Oct 30, 2012 #1326 randerso Initial creation
* Mar 21, 2013 1638 mschenke Created Pair class internal so no dependencies on GFE * Mar 21, 2013 1638 mschenke Created Pair class internal so no dependencies on GFE
* Jul 24, 2013 #1908 randerso Added support for updating attributes when resource cropped.
* Code cleanup
* *
* </pre> * </pre>
* *
@ -87,7 +90,8 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
* @version 1.0 * @version 1.0
*/ */
public class AttributeViewer extends CaveJFACEDialog implements RemoveListener { public class AttributeViewer extends CaveJFACEDialog implements RemoveListener,
IDoubleClickSelectionListener, IAttributesUpdatedListener {
private static final String HIGHLIGHT = "HighLight"; private static final String HIGHLIGHT = "HighLight";
private static final String VISIBLE = "Visible"; private static final String VISIBLE = "Visible";
@ -100,7 +104,7 @@ public class AttributeViewer extends CaveJFACEDialog implements RemoveListener {
* *
* @param shell * @param shell
* @param rsc * @param rsc
* @return * @return the attribute viewer
*/ */
public static AttributeViewer openDialog(Shell shell, DataStoreResource rsc) { public static AttributeViewer openDialog(Shell shell, DataStoreResource rsc) {
AttributeViewer dlg = map.get(rsc); AttributeViewer dlg = map.get(rsc);
@ -213,8 +217,6 @@ public class AttributeViewer extends CaveJFACEDialog implements RemoveListener {
private Object[][] attributes; private Object[][] attributes;
private Shell parentShell;
private TableViewer viewer; private TableViewer viewer;
protected String[] selectedColumns; protected String[] selectedColumns;
@ -225,7 +227,7 @@ public class AttributeViewer extends CaveJFACEDialog implements RemoveListener {
private int[] columnWidth; private int[] columnWidth;
private IDoubleClickSelectionListener selectedListener; private Label rowCount;
/** /**
* Create an attribute viewer for the specified DataStoreResource * Create an attribute viewer for the specified DataStoreResource
@ -243,9 +245,6 @@ public class AttributeViewer extends CaveJFACEDialog implements RemoveListener {
this.title = rsc.getName(); this.title = rsc.getName();
this.names = rsc.getAttributeNames(); this.names = rsc.getAttributeNames();
this.selectedColumns = this.names; this.selectedColumns = this.names;
this.parentShell = parentShell;
// TODO: may need to deep copy this in case it changes out from under us
this.attributes = rsc.getAttributes(); this.attributes = rsc.getAttributes();
map.put(rsc, this); map.put(rsc, this);
@ -431,39 +430,22 @@ public class AttributeViewer extends CaveJFACEDialog implements RemoveListener {
}); });
Label label = new Label(composite, SWT.NONE); rowCount = new Label(composite, SWT.NONE);
label.setText(this.attributes.length + " rows"); rowCount.setText(this.attributes.length + " rows");
layoutData = new GridData(SWT.FILL, SWT.DEFAULT, true, false); layoutData = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
label.setLayoutData(layoutData); rowCount.setLayoutData(layoutData);
initializeColors(); initializeColors();
selectedListener = new IDoubleClickSelectionListener() {
@Override
public void selectedFeaturesChanged(List<String> selectedIds) {
Table table = viewer.getTable();
int i = 0;
table.deselectAll();
for (TableItem item : table.getItems()) {
if (selectedIds.contains(item.getText(0))) {
table.select(i);
}
i++;
}
if (table.getSelectionCount() > 0) {
table.showItem(table.getSelection()[0]);
}
}
};
table.addDisposeListener(new DisposeListener() { table.addDisposeListener(new DisposeListener() {
@Override @Override
public void widgetDisposed(DisposeEvent e) { public void widgetDisposed(DisposeEvent e) {
rsc.removeDoubleClickSelectionListener(selectedListener); rsc.removeDoubleClickSelectionListener(AttributeViewer.this);
rsc.removeAttributesUpdatedListener(AttributeViewer.this);
} }
}); });
rsc.addDoubleClickSelectionListener(selectedListener); rsc.addDoubleClickSelectionListener(this);
rsc.addAttributesUpdatedListener(this);
return composite; return composite;
} }
@ -471,8 +453,8 @@ public class AttributeViewer extends CaveJFACEDialog implements RemoveListener {
private void initializeColors() { private void initializeColors() {
for (TableItem item : viewer.getTable().getItems()) { for (TableItem item : viewer.getTable().getItems()) {
String id = item.getText(0); String id = item.getText(0);
item.setData(VISIBLE, rsc.getVisible(id)); item.setData(VISIBLE, rsc.isVisible(id));
item.setData(HIGHLIGHT, rsc.getHighlighted(id)); item.setData(HIGHLIGHT, rsc.isHighlighted(id));
setColors(item); setColors(item);
} }
} }
@ -640,4 +622,33 @@ public class AttributeViewer extends CaveJFACEDialog implements RemoveListener {
sortDlg.bringToTop(); sortDlg.bringToTop();
} }
} }
@Override
public void selectedFeaturesChanged(List<String> selectedIds) {
Table table = viewer.getTable();
int i = 0;
table.deselectAll();
for (TableItem item : table.getItems()) {
if (selectedIds.contains(item.getText(0))) {
table.select(i);
}
i++;
}
if (table.getSelectionCount() > 0) {
table.showItem(table.getSelection()[0]);
}
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource.
* IAttributesUpdatedListener#attributesUpdated()
*/
@Override
public void attributesUpdated() {
this.attributes = rsc.getAttributes();
viewer.setInput(this.attributes);
rowCount.setText(this.attributes.length + " rows");
}
} }