svn - r34366 - in branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing: . event styling tool utils

1 message Options
Embed this post
Permalink
svn_geotools

svn - r34366 - in branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing: . event styling tool utils

Reply Threaded More More options
Print post
Permalink
Author: mbedward
Date: 2009-11-12 08:52:35 -0500 (Thu, 12 Nov 2009)
New Revision: 34366

Added:
   branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/GridLayerHelper.java
   branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/InfoToolHelper.java
   branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/VectorLayerHelper.java
Removed:
   branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/controls/
   branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/dialogs/
Modified:
   branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/event/MapMouseEvent.java
   branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/styling/JSimpleStyleDialog.java
   branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/InfoTool.java
   branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/utils/MapLayerUtils.java
Log:
GEOT-2831 refactored InfoTool so that it no longer directly references grid coverage classes; these are now loaded lazily via a helper class. Simplified MapLayerUtils. A few minor tweaks.

Modified: branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/event/MapMouseEvent.java
===================================================================
--- branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/event/MapMouseEvent.java 2009-11-12 13:44:01 UTC (rev 34365)
+++ branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/event/MapMouseEvent.java 2009-11-12 13:52:35 UTC (rev 34366)
@@ -61,6 +61,7 @@
         AffineTransform tr = pane.getScreenToWorldTransform();
         geoCoords = new DirectPosition2D(event.getX(), event.getY());
         tr.transform(geoCoords, geoCoords);
+        geoCoords.setCoordinateReferenceSystem(pane.getMapContext().getCoordinateReferenceSystem());
     }
 
     /**
@@ -103,6 +104,8 @@
      * @return a new DirectPosition2D object for the world coordinates
      */
     public DirectPosition2D getMapPosition() {
-        return new DirectPosition2D(geoCoords.x, geoCoords.y);
+        return new DirectPosition2D(
+                geoCoords.getCoordinateReferenceSystem(),
+                geoCoords.x, geoCoords.y);
     }
 }

Modified: branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/styling/JSimpleStyleDialog.java
===================================================================
--- branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/styling/JSimpleStyleDialog.java 2009-11-12 13:44:01 UTC (rev 34365)
+++ branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/styling/JSimpleStyleDialog.java 2009-11-12 13:52:35 UTC (rev 34366)
@@ -212,7 +212,7 @@
         /*
          * Grid coverages and readers are not supported yet...
          */
-        if ((Boolean)MapLayerUtils.isGridLayer(layer).get(MapLayerUtils.IS_GRID_KEY)) {
+        if (MapLayerUtils.isGridLayer(layer)) {
             JOptionPane.showMessageDialog(null,
                     "Sorry, styling for for grid coverages is not working yet",
                     "Style dialog",

Added: branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/GridLayerHelper.java
===================================================================
--- branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/GridLayerHelper.java                        (rev 0)
+++ branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/GridLayerHelper.java 2009-11-12 13:52:35 UTC (rev 34366)
@@ -0,0 +1,138 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+
+package org.geotools.swing.tool;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.geotools.coverage.grid.GridCoverage2D;
+import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
+import org.geotools.geometry.DirectPosition2D;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+
+/**
+ * Helper class used by {@code InfoTool} to query {@code MapLayers}
+ * with raster feature data ({@code GridCoverage2D} or {@code AbstractGridCoverage2DReader}).
+ *
+ * @see InfoTool
+ * @see VectorLayerHelper
+ *
+ * @author Michael Bedward
+ * @since 2.6
+ * @source $Id$
+ * @version $URL$
+ */
+public class GridLayerHelper extends InfoToolHelper<List<Number>> {
+    protected final GridCoverage2D cov;
+
+    /**
+     * Create a new helper to work with the given raster data source.
+     *
+     * @param rasterSource an instance of either
+     *        {@code GridCoverage2D} or {@code AbstractGridCoverage2DReader
+     */
+    public GridLayerHelper(Object rasterSource) {
+        super(Type.GRID_HELPER);
+
+        System.out.println("Creating GridLayerHelper instance");
+
+        try {
+            if (AbstractGridCoverage2DReader.class.isAssignableFrom(rasterSource.getClass())) {
+                this.cov = ((AbstractGridCoverage2DReader) rasterSource).read(null);
+            } else {
+                this.cov = (GridCoverage2D) rasterSource;
+            }
+        } catch (Exception ex) {
+            throw new IllegalArgumentException(ex);
+        }
+    }
+
+    /**
+     * Get band values at the given position
+     *
+     * @param pos the location to query
+     *
+     * @param params currently ignored
+     *
+     * @return a {@code List} of band values; will be empty if {@code pos} was
+     *         outside the coverage bounds
+     *
+     * @throws Exception if the grid coverage could not be queried
+     */
+    @Override
+    public List<Number> getInfo(DirectPosition2D pos, Object ...params)
+            throws Exception {
+        
+        List<Number> list = new ArrayList<Number>();
+
+        ReferencedEnvelope env = new ReferencedEnvelope(this.cov.getEnvelope2D());
+        if (env.contains(pos)) {
+            Object objArray = cov.evaluate(pos);
+            Number[] bandValues = asNumberArray(objArray);
+            if (bandValues != null) {
+                for (Number value : bandValues) {
+                    list.add(value);
+                }
+            }
+        }
+
+        return list;
+    }
+
+    /**
+     * Convert the Object returned by {@linkplain GridCoverage2D#evaluate(DirectPosition)} into
+     * an array of {@code Numbers}.
+     *
+     * @param objArray an Object representing a primitive array
+     *
+     * @return a new array of Numbers
+     */
+    private Number[] asNumberArray(Object objArray) {
+        Number[] numbers = null;
+
+        if (objArray instanceof byte[]) {
+            byte[] values = (byte[]) objArray;
+            numbers = new Number[values.length];
+            for (int i = 0; i < values.length; i++) {
+                numbers[i] = ((int)values[i]) & 0xff;
+            }
+
+        } else if (objArray instanceof int[]) {
+            int[] values = (int[]) objArray;
+            numbers = new Number[values.length];
+            for (int i = 0; i < values.length; i++) {
+                numbers[i] = values[i];
+            }
+
+        } else if (objArray instanceof float[]) {
+            float[] values = (float[]) objArray;
+            numbers = new Number[values.length];
+            for (int i = 0; i < values.length; i++) {
+                numbers[i] = values[i];
+            }
+        } else if (objArray instanceof double[]) {
+            double[] values = (double[]) objArray;
+            numbers = new Number[values.length];
+            for (int i = 0; i < values.length; i++) {
+                numbers[i] = values[i];
+            }
+        }
+
+        return numbers;
+    }
+
+}


Property changes on: branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/GridLayerHelper.java
___________________________________________________________________
Added: svn:keywords
   + Id URL

Modified: branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/InfoTool.java
===================================================================
--- branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/InfoTool.java 2009-11-12 13:44:01 UTC (rev 34365)
+++ branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/InfoTool.java 2009-11-12 13:52:35 UTC (rev 34366)
@@ -17,25 +17,19 @@
 
 package org.geotools.swing.tool;
 
-import com.vividsolutions.jts.geom.Coordinate;
 import com.vividsolutions.jts.geom.Geometry;
 import com.vividsolutions.jts.geom.GeometryFactory;
-import com.vividsolutions.jts.geom.MultiPolygon;
-import com.vividsolutions.jts.geom.Polygon;
 import java.awt.Cursor;
 import java.awt.Dimension;
 import java.awt.Point;
 import java.awt.Toolkit;
 import java.awt.event.WindowEvent;
-import java.io.IOException;
+import java.lang.reflect.Constructor;
 import java.util.Collection;
-import java.util.Map;
+import java.util.List;
 import java.util.ResourceBundle;
+import java.util.WeakHashMap;
 import javax.swing.ImageIcon;
-import org.geotools.coverage.grid.GridCoverage2D;
-import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
-import org.geotools.factory.CommonFactoryFinder;
-import org.geotools.factory.GeoTools;
 import org.geotools.feature.FeatureCollection;
 import org.geotools.feature.FeatureIterator;
 import org.geotools.geometry.DirectPosition2D;
@@ -46,18 +40,20 @@
 import org.geotools.swing.TextReporterListener;
 import org.geotools.swing.event.MapMouseEvent;
 import org.geotools.swing.utils.MapLayerUtils;
-import org.opengis.coverage.CannotEvaluateException;
 import org.opengis.feature.Feature;
 import org.opengis.feature.Property;
-import org.opengis.feature.type.FeatureType;
 import org.opengis.feature.type.GeometryDescriptor;
-import org.opengis.filter.Filter;
-import org.opengis.filter.FilterFactory2;
 
 /**
  * A cursor tool to retrieve information about features that the user clicks
- * on with the mouse.
+ * on with the mouse. It works with {@code InfoToolHelper} objects which do
+ * the work of querying feature data. The primary reason for this design
+ * is to shield this class from the grid coverage classes so that
+ * users who are working purely with vector data are not forced to have
+ * JAI in the classpath.
  *
+ * @see InfoToolHelper
+ *
  * @author Michael Bedward
  * @since 2.6
  * @source $Id$
@@ -89,11 +85,11 @@
     public static final double DEFAULT_DISTANCE_FRACTION = 0.01d;
 
     private Cursor cursor;
-    private FilterFactory2 filterFactory;
-    private GeometryFactory geomFactory;
 
     private JTextReporter reporter;
 
+    private WeakHashMap<MapLayer, InfoToolHelper> helperTable;
+
     /**
      * Constructor
      */
@@ -107,8 +103,8 @@
         Dimension bestCursorSize = tk.getBestCursorSize(cursorIcon.getIconWidth(), cursorIcon.getIconHeight());
 
         cursor = tk.createCustomCursor(cursorIcon.getImage(), CURSOR_HOTSPOT, TOOL_TIP);
-        filterFactory = CommonFactoryFinder.getFilterFactory2(GeoTools.getDefaultHints());
-        geomFactory = new GeometryFactory();
+
+        helperTable = new WeakHashMap<MapLayer, InfoToolHelper>();
     }
 
     @Override
@@ -116,9 +112,12 @@
         DirectPosition2D pos = ev.getMapPosition();
         report(pos);
 
+        FeatureIterator<? extends Feature> iter = null;
+
         for (MapLayer layer : getMapPane().getMapContext().getLayers()) {
-            FeatureIterator<? extends Feature> iter = null;
             if (layer.isSelected()) {
+                InfoToolHelper helper = null;
+
                 String layerName = layer.getTitle();
                 if (layerName == null || layerName.length() == 0) {
                     layerName = layer.getFeatureSource().getName().getLocalPart();
@@ -127,83 +126,84 @@
                     layerName = layer.getFeatureSource().getSchema().getName().getLocalPart();
                 }
 
-                try {
-                    Map<String, Object> result = MapLayerUtils.isGridLayer(layer);
-                    if ((Boolean)result.get(MapLayerUtils.IS_GRID_KEY)) {
-                        /*
-                         * For grid coverages we directly evaluate the band values
-                         */
-                        iter = layer.getFeatureSource().getFeatures().features();
-                        String gridAttr = (String) result.get(MapLayerUtils.GRID_ATTR_KEY);
-                        Object obj = iter.next().getProperty(gridAttr).getValue();
-                        GridCoverage2D cov = null;
 
-                        if ((Boolean)result.get(MapLayerUtils.IS_GRID_READER_KEY)) {
-                            AbstractGridCoverage2DReader reader = (AbstractGridCoverage2DReader) obj;
-                            cov = reader.read(null);
-                        } else {
-                            cov = (GridCoverage2D) obj;
-                        }
-
+                helper = helperTable.get(layer);
+                if (helper == null) {
+                    if (MapLayerUtils.isGridLayer(layer)) {
+                        String gridAttrName = MapLayerUtils.getGridAttributeName(layer);
                         try {
-                            Object objArray = cov.evaluate(pos);
-                            Number[] bandValues = asNumberArray(objArray);
-                            report(layerName, bandValues);
+                            iter = layer.getFeatureSource().getFeatures().features();
+                            Object rasterSource = iter.next().getProperty(gridAttrName).getValue();
+                            Class<?> clazz = Class.forName("org.geotools.swing.tool.GridLayerHelper");
+                            Constructor<?> ctor = clazz.getConstructor(Object.class);
+                            helper = (InfoToolHelper) ctor.newInstance(rasterSource);
+                            helperTable.put(layer, helper);
 
-                        } catch (CannotEvaluateException ex) {
-                            // do nothing - point outside coverage
+                        } catch (Exception ex) {
+                            throw new IllegalStateException("Failed to create InfoToolHelper for grid layer", ex);
+
+                        } finally {
+                            iter.close();
                         }
 
                     } else {
-                        /*
-                         * Handling a vector layer
-                         */
-                        Filter filter = null;
                         GeometryDescriptor geomDesc = layer.getFeatureSource().getSchema().getGeometryDescriptor();
                         String attrName = geomDesc.getLocalName();
                         Class<?> geomClass = geomDesc.getType().getBinding();
 
-                        if (Polygon.class.isAssignableFrom(geomClass) ||
-                                MultiPolygon.class.isAssignableFrom(geomClass)) {
-                            /*
-                             * Polygon features - use an intersects filter
-                             */
-                            Geometry posGeom = geometryFactory.createPoint(new Coordinate(pos.x, pos.y));
-                            /*
-                             * For polygons we test if they contain mouse location
-                             */
-                            filter = filterFactory.intersects(
-                                    filterFactory.property(attrName),
-                                    filterFactory.literal(posGeom));
-                        } else {
-                            /*
-                             * Line or point features - use a bounding box filter
-                             */
-                            ReferencedEnvelope mapEnv = getMapPane().getDisplayArea();
-                            double searchWidth =  DEFAULT_DISTANCE_FRACTION * (mapEnv.getWidth() + mapEnv.getHeight()) / 2;
+                        try {
+                            Class<?> clazz = Class.forName("org.geotools.swing.tool.VectorLayerHelper");
+                            Constructor<?> ctor = clazz.getConstructor(MapLayer.class, String.class, Class.class);
+                            helper = (InfoToolHelper) ctor.newInstance(layer, attrName, geomClass);
+                            helperTable.put(layer, helper);
 
-                            ReferencedEnvelope searchBounds = new ReferencedEnvelope(
-                                    pos.x - searchWidth,
-                                    pos.x + searchWidth,
-                                    pos.y - searchWidth,
-                                    pos.y + searchWidth,
-                                    getMapPane().getMapContext().getCoordinateReferenceSystem());
-
-                            filter = filterFactory.bbox(filterFactory.property(attrName), searchBounds);
+                        } catch (Exception ex) {
+                            throw new IllegalStateException("Failed to create InfoToolHelper for vector layer", ex);
                         }
-                        FeatureCollection<? extends FeatureType, ? extends Feature> selectedFeatures =
-                                layer.getFeatureSource().getFeatures(filter);
+                    }
+                }
 
-                        iter = selectedFeatures.features();
-                        while (iter.hasNext()) {
-                            report(layerName, iter.next());
+                Object info = null;
+
+                if (helper.getType() == InfoToolHelper.Type.VECTOR_HELPER) {
+                    ReferencedEnvelope mapEnv = getMapPane().getDisplayArea();
+                    double searchWidth = DEFAULT_DISTANCE_FRACTION * (mapEnv.getWidth() + mapEnv.getHeight()) / 2;
+                    try {
+                        info = helper.getInfo(pos, Double.valueOf(searchWidth));
+                    } catch (Exception ex) {
+                        throw new IllegalStateException(ex);
+                    }
+
+                    if (info != null) {
+                        FeatureCollection selectedFeatures = (FeatureCollection) info;
+                        try {
+                            iter = selectedFeatures.features();
+                            while (iter.hasNext()) {
+                                report(layerName, iter.next());
+                            }
+
+                        } catch (Exception ex) {
+                            throw new IllegalStateException(ex);
+
+                        } finally {
+                            if (iter != null) {
+                                iter.close();
+                            }
                         }
+                    }
 
+                } else {
+                    try {
+                        info = helper.getInfo(pos);
+                    } catch (Exception ex) {
+                        throw new IllegalStateException(ex);
                     }
-                } catch (IOException ioEx) {
-                } finally {
-                    if (iter != null) {
-                        iter.close();
+
+                    if (info != null) {
+                        List<Number> bandValues = (List<Number>) info;
+                        if (!bandValues.isEmpty()) {
+                            report(layerName, bandValues);
+                        }
                     }
                 }
             }
@@ -261,14 +261,15 @@
      * @param layerName name of the map layer that contains the grid coverage
      * @param bandValues array of values
      */
-    private void report(String layerName, Number[] bandValues) {
+    private void report(String layerName, List<Number> bandValues) {
         createReporter();
 
         reporter.append(layerName);
         reporter.append("\n");
 
-        for (int i = 0; i < bandValues.length; i++) {
-            reporter.append(String.format("  Band %d: %s\n", (i+1), bandValues[i].toString()));
+        int k = 1;
+        for (Number value : bandValues) {
+            reporter.append(String.format("  Band %d: %s\n", k++, value.toString()));
         }
         reporter.append("\n");
     }
@@ -314,45 +315,4 @@
         // no action
     }
 
-    /**
-     * Convert the Object returned by {@linkplain GridCoverage2D#evaluate(DirectPosition)} into
-     * an array of Numbers
-     *
-     * @param objArray an Object representing a primitive array
-     *
-     * @return a new array of Numbers
-     */
-    private Number[] asNumberArray(Object objArray) {
-        Number[] numbers = null;
-
-        if (objArray instanceof byte[]) {
-            byte[] values = (byte[]) objArray;
-            numbers = new Number[values.length];
-            for (int i = 0; i < values.length; i++) {
-                numbers[i] = ((int)values[i]) & 0xff;
-            }
-
-        } else if (objArray instanceof int[]) {
-            int[] values = (int[]) objArray;
-            numbers = new Number[values.length];
-            for (int i = 0; i < values.length; i++) {
-                numbers[i] = values[i];
-            }
-
-        } else if (objArray instanceof float[]) {
-            float[] values = (float[]) objArray;
-            numbers = new Number[values.length];
-            for (int i = 0; i < values.length; i++) {
-                numbers[i] = values[i];
-            }
-        } else if (objArray instanceof double[]) {
-            double[] values = (double[]) objArray;
-            numbers = new Number[values.length];
-            for (int i = 0; i < values.length; i++) {
-                numbers[i] = values[i];
-            }
-        }
-
-        return numbers;
-    }
 }

Added: branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/InfoToolHelper.java
===================================================================
--- branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/InfoToolHelper.java                        (rev 0)
+++ branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/InfoToolHelper.java 2009-11-12 13:52:35 UTC (rev 34366)
@@ -0,0 +1,56 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+
+package org.geotools.swing.tool;
+
+import java.util.Map;
+import org.geotools.geometry.DirectPosition2D;
+
+/**
+ * Abstract base class for helper classes used by {@code InfoTool} to query
+ * {@code MapLayers}. The primary reason for having this class is to avoid
+ * loading grid coverage classes unless they are really needed, and thus
+ * avoid the need for users to have JAI in the classpath when working with
+ * vector data.
+ *
+ * @see InfoTool
+ *
+ * @author Michael Bedward
+ * @since 2.6
+ * @source $Id$
+ * @version $URL$
+ */
+public abstract class InfoToolHelper<T> {
+
+    public static enum Type {
+        GRID_HELPER, VECTOR_HELPER;
+    }
+
+    private final Type type;
+
+    protected InfoToolHelper(Type type) {
+        this.type = type;
+    }
+
+    public abstract T getInfo(DirectPosition2D pos, Object ...params) throws Exception;
+
+    public Type getType() {
+        return type;
+    }
+
+}
+


Property changes on: branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/InfoToolHelper.java
___________________________________________________________________
Added: svn:keywords
   + Id URL

Added: branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/VectorLayerHelper.java
===================================================================
--- branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/VectorLayerHelper.java                        (rev 0)
+++ branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/VectorLayerHelper.java 2009-11-12 13:52:35 UTC (rev 34366)
@@ -0,0 +1,134 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+
+package org.geotools.swing.tool;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Polygon;
+import java.lang.ref.WeakReference;
+import org.geotools.factory.CommonFactoryFinder;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.geometry.DirectPosition2D;
+import org.geotools.geometry.jts.JTSFactoryFinder;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.map.MapLayer;
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+import org.opengis.filter.Filter;
+import org.opengis.filter.FilterFactory2;
+
+/**
+ * Helper class used by {@code InfoTool} to query {@code MapLayers}
+ * with vector feature data.
+ * <p>
+ * Implementation note: this class keeps only a weak reference to
+ * the {@code MapLayer} it is working with to avoid memory leaks if
+ * the layer is deleted.
+ *
+ * @see InfoTool
+ * @see GridLayerHelper
+ *
+ * @author Michael Bedward
+ * @since 2.6
+ * @source $Id$
+ * @version $URL$
+ */
+public class VectorLayerHelper extends InfoToolHelper<FeatureCollection> {
+    
+    private static final GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
+    private static final FilterFactory2 filterFactory = CommonFactoryFinder.getFilterFactory2(null);
+    
+    private final WeakReference<MapLayer> layerReference;
+    private final String attrName;
+    private final boolean isPolygonGeometry;
+
+    /**
+     * Create a new helper to work with {@code MapLayers} having vector feature data.
+     *
+     * @param layer the map layer
+     *
+     * @param geomAttributeName the name of the geometry attribute for {@code Features}
+     *
+     * @param geomClass the geometry class
+     */
+    public VectorLayerHelper(MapLayer layer, String geomAttributeName, Class<?> geomClass) {
+        super(Type.VECTOR_HELPER);
+
+        System.out.println("Creating VectorLayerHelper instance");
+
+        this.layerReference = new WeakReference<MapLayer>(layer);
+        this.attrName = geomAttributeName;
+
+        isPolygonGeometry = (Polygon.class.isAssignableFrom(geomClass) ||
+                MultiPolygon.class.isAssignableFrom(geomClass));
+    }
+
+    /**
+     * Get feature data at the given position.
+     *
+     * @param pos the location to query
+     *
+     * @param params a {@code Double} value for the search radius to use with
+     *        point or line features
+     *
+     * @return
+     *
+     * @throws Exception
+     */
+    public FeatureCollection getInfo(DirectPosition2D pos, Object ...params)
+            throws Exception {
+
+        FeatureCollection<? extends FeatureType, ? extends Feature> collection = null;
+        MapLayer layer = layerReference.get();
+
+        if (layer != null) {
+            Filter filter = null;
+            if (isPolygonGeometry) {
+                /*
+                 * Polygon features - use an intersects filter
+                 */
+                Geometry posGeom = geometryFactory.createPoint(new Coordinate(pos.x, pos.y));
+                filter = filterFactory.intersects(
+                        filterFactory.property(attrName),
+                        filterFactory.literal(posGeom));
+
+        } else {
+                /*
+                 * Line or point features - use a bounding box filter
+                 */
+                double radius = ((Number) params[0]).doubleValue();
+
+                ReferencedEnvelope searchBounds = new ReferencedEnvelope(
+                        pos.x - radius,
+                        pos.x + radius,
+                        pos.y - radius,
+                        pos.y + radius,
+                        pos.getCoordinateReferenceSystem());
+
+                filter = filterFactory.bbox(filterFactory.property(attrName), searchBounds);
+            }
+
+            collection = layer.getFeatureSource().getFeatures(filter);
+        }
+
+        return collection;
+    }
+    
+}


Property changes on: branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/tool/VectorLayerHelper.java
___________________________________________________________________
Added: svn:keywords
   + Id URL

Modified: branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/utils/MapLayerUtils.java
===================================================================
--- branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/utils/MapLayerUtils.java 2009-11-12 13:44:01 UTC (rev 34365)
+++ branches/2.6.x/modules/unsupported/swing/src/main/java/org/geotools/swing/utils/MapLayerUtils.java 2009-11-12 13:52:35 UTC (rev 34366)
@@ -17,11 +17,7 @@
 package org.geotools.swing.utils;
 
 import java.util.Collection;
-import java.util.Map;
-import org.geotools.coverage.grid.GridCoverage2D;
-import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
 import org.geotools.map.MapLayer;
-import org.geotools.util.KVP;
 import org.opengis.feature.type.PropertyDescriptor;
 
 /**
@@ -36,63 +32,46 @@
  */
 public class MapLayerUtils {
 
-    /**
-     * Key for the boolean value in the {@code Map} returned by {@linkplain #isGridLayer}
-     * that indicates whether the layer contained a grid (or grid reader)
-     */
-    public static final String IS_GRID_KEY = "is_grid";
+    private static final String GRID_PACKAGE = "org.geotools.coverage.grid";
 
     /**
-     * Key for the boolean value in the {@code Map} returned by {@linkplain #isGridLayer}
-     * that indicates whether the layer contained a grid reader
-     */
-    public static final String IS_GRID_READER_KEY = "is_grid_reader";
-    
-    /**
-     * Key for the String value in the {@code Map} returned by {@linkplain #isGridLayer}
-     * that has the name of the grid attribute in the layer's feature collection; or an
-     * empty string if there is no grid attribute
-     */
-    public static final String GRID_ATTR_KEY = "grid_attr";
-
-    /**
      * Check if the given map layer contains a grid coverage or a grid coverage reader.
+     * <p>
+     * Implementation note: we avoid referencing org.geotools.coverage.grid classes
+     * directly here so that applications dealing only with other data types are not
+     * forced to have JAI in the classpath.
      *
      * @param layer the map layer
-     * @return a {@code Map} containing:
-     * <ul>
-     * <li> {@linkplain #IS_GRID_KEY}: (Boolean) true if the layer has a grid coverage
-     *      or grid coverage reader
-     * <li> {@linkplain #IS_GRID_READER_KEY}: (Boolean) true if the layer has a grid
-     *      coverage reader
-     * <li> {@linkplain #GRID_ATTR_KEY}: (String) the name of the attribute in the layer's
-     *      feature collection that contains the grid coverage or reader
-     * </ul>
+     *
+     * @return true if this is a grid layer; false otherwise
      */
-    public static Map<String, Object> isGridLayer(MapLayer layer) {
-        KVP info = new KVP(
-                IS_GRID_KEY, Boolean.FALSE,
-                IS_GRID_READER_KEY, Boolean.FALSE,
-                GRID_ATTR_KEY, "");
+    public static boolean isGridLayer(MapLayer layer) {
 
         Collection<PropertyDescriptor> descriptors = layer.getFeatureSource().getSchema().getDescriptors();
         for (PropertyDescriptor desc : descriptors) {
-            Class<?> clazz = desc.getType().getBinding();
+            String className = desc.getType().getBinding().getName();
 
-            if (GridCoverage2D.class.isAssignableFrom(clazz)) {
-                info.put(IS_GRID_KEY, Boolean.TRUE);
-                info.put(GRID_ATTR_KEY, desc.getName().getLocalPart());
-                break;
+            if (className.contains(GRID_PACKAGE)) {
+                return true;
+            }
+        }
 
-            } else if (AbstractGridCoverage2DReader.class.isAssignableFrom(clazz)) {
-                info.put(IS_GRID_KEY, Boolean.TRUE);
-                info.put(IS_GRID_READER_KEY, Boolean.TRUE);
-                info.put(GRID_ATTR_KEY, desc.getName().getLocalPart());
+        return false;
+    }
+
+    public static String getGridAttributeName(MapLayer layer) {
+        String attrName = null;
+
+        Collection<PropertyDescriptor> descriptors = layer.getFeatureSource().getSchema().getDescriptors();
+        for (PropertyDescriptor desc : descriptors) {
+            String className = desc.getType().getBinding().getName();
+
+            if (className.contains(GRID_PACKAGE)) {
+                attrName = desc.getName().getLocalPart();
                 break;
             }
         }
 
-        return info;
+        return attrName;
     }
-
 }


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
GeoTools-commits mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/geotools-commits