/[schmitzm]/trunk/src/skrueger/geotools/StyledFeatureCollectionTableModel.java
ViewVC logotype

Diff of /trunk/src/skrueger/geotools/StyledFeatureCollectionTableModel.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/src/skrueger/geotools/StyledFeatureCollectionTableModel.java revision 112 by mojays, Wed May 13 09:18:53 2009 UTC branches/1.0-gt2-2.6/src/skrueger/geotools/StyledFeatureCollectionTableModel.java revision 335 by alfonx, Wed Aug 26 18:09:39 2009 UTC
# Line 1  Line 1 
1  /** SCHMITZM - This file is part of the java library of Martin O.J. Schmitz (SCHMITZM)  /*******************************************************************************
2     * Copyright (c) 2009 Martin O. J. Schmitz.
3      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; either version 2.1 of the License, or (at your option) any later version.   *
4      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.   * This file is part of the SCHMITZM library - a collection of utility
5      You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA   * classes based on Java 1.6, focusing (not only) on Java Swing
6     * and the Geotools library.
7      Diese Bibliothek ist freie Software; Sie dürfen sie unter den Bedingungen der GNU Lesser General Public License, wie von der Free Software Foundation veröffentlicht, weiterverteilen und/oder modifizieren; entweder gemäß Version 2.1 der Lizenz oder (nach Ihrer Option) jeder späteren Version.   *
8      Diese Bibliothek wird in der Hoffnung weiterverbreitet, daß sie nützlich sein wird, jedoch OHNE IRGENDEINE GARANTIE, auch ohne die implizierte Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Mehr Details finden Sie in der GNU Lesser General Public License.   * The SCHMITZM project is hosted at:
9      Sie sollten eine Kopie der GNU Lesser General Public License zusammen mit dieser Bibliothek erhalten haben; falls nicht, schreiben Sie an die Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.   * http://wald.intevation.org/projects/schmitzm/
10   **/   *
11  package skrueger.geotools;   * This program is free software; you can redistribute it and/or
12     * modify it under the terms of the GNU Lesser General Public License
13     * as published by the Free Software Foundation; either version 3
14  import java.util.Iterator;   * of the License, or (at your option) any later version.
15  import java.util.Map;   *
16  import java.util.TreeMap;   * This program is distributed in the hope that it will be useful,
17  import java.util.Vector;   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  import org.apache.log4j.Logger;   * GNU General Public License for more details.
20  import org.geotools.data.DefaultQuery;   *
21  import org.geotools.data.FeatureSource;   * You should have received a copy of the GNU Lesser General Public License (license.txt)
22  import org.geotools.data.Query;   * along with this program; if not, write to the Free Software
23  import org.geotools.data.memory.MemoryDataStore;   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
24  import org.geotools.feature.FeatureCollection;   * or try this link: http://www.gnu.org/licenses/lgpl.html
25  import org.opengis.filter.Filter;   *
26     * Contributors:
27  import com.vividsolutions.jts.geom.Envelope;   *     Martin O. J. Schmitz - initial API and implementation
28     *     Stefan A. Krüger - additional utility classes
29  import schmitzm.geotools.gui.FeatureCollectionTableModel;   ******************************************************************************/
30  import skrueger.AttributeMetaData;  package skrueger.geotools;
31  import skrueger.i8n.I8NUtil;  
32  import skrueger.i8n.Translation;  import java.util.Iterator;
33    import java.util.Map;
34  /**  import java.util.Vector;
35   * This class extends the the {@link FeatureCollectionTableModel} with the  
36   * functionalities of the {@link AttributeMetaData} of  import org.apache.log4j.Logger;
37   * {@linkplain StyledMapInterface styled objects}.  import org.geotools.data.DefaultQuery;
38   * <ul>  import org.geotools.data.FeatureSource;
39   *   <li>column names are translated according to {@link AttributeMetaData#getTitle()}</li>  import org.geotools.data.Query;
40   *   <li>columns are hidden according to {@link AttributeMetaData#isVisible()()}</li>  import org.geotools.data.memory.MemoryDataStore;
41   * </ul>  import org.geotools.feature.FeatureCollection;
42   * @author <a href="mailto:[email protected]">Martin Schmitz</a> (University of Bonn/Germany)  import org.opengis.feature.simple.SimpleFeature;
43   */  import org.opengis.feature.simple.SimpleFeatureType;
44  public class StyledFeatureCollectionTableModel extends FeatureCollectionTableModel {  import org.opengis.feature.type.AttributeDescriptor;
45    final static private Logger LOGGER = Logger.getLogger(StyledFeatureCollectionTableModel.class);  import org.opengis.feature.type.FeatureType;
46    /** Holds the data source as styled map. */  import org.opengis.filter.Filter;
47    protected StyledMapInterface<?> map = null;  
48    /** Contains only the visible elements of the {@link AttributeMetaData}-Map */  import schmitzm.geotools.gui.FeatureCollectionTableModel;
49    protected Map<Integer, AttributeMetaData> visibleAMD = null;  import skrueger.AttributeMetaData;
50    /** Holds the data source for the table as {@code FeatureSource}. */  import skrueger.i8n.I8NUtil;
51    protected FeatureSource featureSource = null;  import skrueger.i8n.Translation;
52    /** Contains the complete {@link AttributeMetaData}-Map of the styled layer. */  
53    protected Map<Integer, AttributeMetaData> origAMD = null;  import com.vividsolutions.jts.geom.Envelope;
54    /** Holds the current filter on the table */  
55    protected Filter filter = null;  /**
56    /** Holds the Bounds for all features. Only set once during the constructor **/   * This class extends the the {@link FeatureCollectionTableModel} with the
57    protected Envelope bounds;   * functionalities of the {@link AttributeMetaData} of
58     * {@linkplain StyledLayerInterface styled objects}.
59    /**   * <ul>
60     * Creates a new table model for a styled map.   * <li>column names are translated according to
61     * @param map the styled map   * {@link AttributeMetaData#getTitle()}</li>
62     */   * <li>columns are hidden according to {@link AttributeMetaData#isVisible()()}</li>
63    public StyledFeatureCollectionTableModel(StyledFeatureCollectionInterface map) {   * </ul>
64      this(map,Filter.INCLUDE);   *
65    }   * @author <a href="mailto:[email protected]">Martin Schmitz</a>
66     *         (University of Bonn/Germany)
67    /**   */
68     * Creates a new table model for a styled map.  public class StyledFeatureCollectionTableModel extends
69     * @param map the styled map                  FeatureCollectionTableModel {
70     * @param filter filter applied to the table          final static private Logger LOGGER = Logger
71     */                          .getLogger(StyledFeatureCollectionTableModel.class);
72    public StyledFeatureCollectionTableModel(StyledFeatureCollectionInterface map, Filter filter) {          /** Holds the data source as styled layer. */
73      super();          protected StyledLayerInterface<?> layer = null;
74      setFeatureCollection(map, filter);          /** Contains only the visible elements of the {@link AttributeMetaData}-Map */
75    }          protected Map<Integer, AttributeMetaData> visibleAMD = null;
76            /** Holds the data source for the table as {@code FeatureSource}. */
77    /**          protected FeatureSource featureSource = null;
78     * Creates a new table model for a styled map.          /** Contains the complete {@link AttributeMetaData}-Map of the styled layer. */
79     * @param map the styled map          protected Map<Integer, AttributeMetaData> origAMD = null;
80     */          /** Holds the current filter on the table */
81    public StyledFeatureCollectionTableModel(StyledFeatureSourceInterface map) {          protected Filter filter = null;
82      this(map,Filter.INCLUDE);          /** Holds the Bounds for all features. Only set once during the constructor **/
83    }          protected Envelope bounds;
84    
85    /**          
86     * Creates a new table model for a styled map.  
87     * @param map the styled map          /**
88     * @param filter filter applied to the table           * Creates a new table model for a styled layer.
89     */           *
90    public StyledFeatureCollectionTableModel(StyledFeatureSourceInterface map, Filter filter) {           * @param layer
91      super();           *            the styled layer
92      setFeatureCollection(map, filter);           */
93    }          public StyledFeatureCollectionTableModel(
94                            StyledFeatureCollectionInterface layer) {
95    /**                  this(layer, Filter.INCLUDE);
96     * Sets a new data source for the table.          }
97     * @param fs     the feature source  
98     * @param amd    {@link AttributeMetaData}-Map to define the visible attributes          /**
99     *               and translation           * Creates a new table model for a styled layer.
100     */           *
101    protected void setFeatureSource(FeatureSource fs, Map<Integer, AttributeMetaData> amd, Filter filter) throws Exception {           * @param layer
102      if ( filter == null )           *            the styled layer
103        filter = Filter.INCLUDE;           * @param filter
104                 *            filter applied to the table
105      this.featureSource = fs;           */
106      this.filter        = filter;          public StyledFeatureCollectionTableModel(
107      this.origAMD       = amd;                          StyledFeatureCollectionInterface layer, Filter filter) {
108      this.visibleAMD    = null;                  super();
109                        setFeatureCollection(layer, filter);
110      FeatureCollection fc = null;          }
111      if (fs != null) {  
112            
113         bounds = fs.getBounds();          /**
114                     * Creates a new table model for a styled layer.
115        Query query = new DefaultQuery(fs.getSchema().getTypeName(), filter);           *
116        if (amd != null) {           * @param layer
117          // determine the names of the visible Attributes           *            the styled layer
118          this.visibleAMD = StyledMapUtil.getVisibleAttributeMetaData(amd, true);           */
119          Vector<String> visibleAttrNames = new Vector<String>();          public StyledFeatureCollectionTableModel(StyledFeaturesInterface layer) {
120          // Add the column with the geometry (usually "the_geom")                  this(layer, Filter.INCLUDE);
121          visibleAttrNames.add(fs.getSchema().getDefaultGeometry().getLocalName());          }
122          for (int attrIdx : visibleAMD.keySet())  
123            visibleAttrNames.add(fs.getSchema().getAttributeType(attrIdx).getLocalName());          /**
124             * Creates a new table model for a styled layer.
125          // create a query for the visible attributes           *
126          String[] properties = visibleAttrNames.toArray(new String[0]);           * @param layer
127                     *            the styled layer
128          LOGGER.debug("Query contains the following attributes: " + visibleAttrNames);           * @param filter
129                     *            filter applied to the table
130          query = new DefaultQuery(fs.getSchema().getTypeName(), filter, properties);           */
131        }          public StyledFeatureCollectionTableModel(StyledFeaturesInterface layer,
132        fc = fs.getFeatures(query);                          Filter filter) {
133                    super();
134  // FAILS:!!!, even with  query = new DefaultQuery(fs.getSchema().getTypeName(), filter);                  setFeatureCollection(layer, filter);
135                          // java.lang.UnsupportedOperationException: Unknown feature          }
136                          // attribute: PQM_MOD  
137                          // at          /**
138                          // schmitzm.geotools.feature.FeatureOperationTree.evaluate(FeatureOperationTree.java:93)           * Sets a new data source for the table.
139                          // bounds = fc.getBounds();           *
140                          // SK, 17.4.2009           * @param fs
141                          //                 *            the feature source
142                          // System.out.println("Filter = "+filter);           * @param amd
143                          // System.out.println("Size of FC = "+fc.size());           *            {@link AttributeMetaData}-Map to define the visible attributes
144                          // System.out.println("anz att= "+fc.getNumberOfAttributes());           *            and translation
145      }           */
146      setFeatureCollection(fc);          protected void setFeatureSource(FeatureSource<SimpleFeatureType, SimpleFeature> fs,
147    }                          Map<Integer, AttributeMetaData> amd, Filter filter)
148                            throws Exception {
149    /**                  if (filter == null)
150     * Converts the {@code StyledFeatureCollection} to a {@code FeatureSource}                          filter = Filter.INCLUDE;
151     * and sets this as the new data source for the table.  
152     * @param fs     the feature source                  this.featureSource = fs;
153     * @param amd    {@link AttributeMetaData}-Map to define the visible attributes                  this.filter = filter;
154     *               and translation                  this.origAMD = amd;
155     */                  this.visibleAMD = null;
156    public void setFeatureCollection(StyledFeatureCollectionInterface map, Filter filter) {  
157      this.map = map;                  FeatureCollection fc = null;
158      try {                  if (fs != null) {
159        if (map == null)  
160          setFeatureSource(null, null, null);                          bounds = fs.getBounds();
161        else {  
162          FeatureCollection fc = map.getGeoObject();                          Query query = new DefaultQuery(fs.getSchema().getName().getLocalPart(), filter);
163          String fcName = fc.getSchema().getTypeName();                          if (amd != null) {
164          FeatureSource fs = new MemoryDataStore(fc).getFeatureSource(fcName);                                  // determine the names of the visible Attributes
165          setFeatureSource(fs, map.getAttributeMetaDataMap(), filter);                                  this.visibleAMD = StyledLayerUtil.getVisibleAttributeMetaData(
166        }                                                  amd, true);
167      } catch (Exception err) {                                  Vector<String> visibleAttrNames = new Vector<String>();
168        throw new RuntimeException(err);                                  // Add the column with the geometry (usually "the_geom")
169      }                                  visibleAttrNames.add(fs.getSchema().getGeometryDescriptor()
170    }                                                  .getLocalName());
171                                    for (int attrIdx : visibleAMD.keySet()) {
172    /**  
173     * Sets the {@code StyledFeatureCollection} as new data source for the table.                                          /**
174     * @param fs     the feature source                                           * If the user removed columns from the schema of the DBF
175     * @param amd    {@link AttributeMetaData}-Map to define the visible attributes                                           * file, there might exist AttributeMetaData for columns
176     *               and translation                                           * that don't exists. We check here to avoid an
177     */                                           * ArrayOutOfIndex.
178    public void setFeatureCollection(StyledFeatureSourceInterface map, Filter filter) {                                           */
179      this.map = map;                                          if (attrIdx < fs.getSchema().getAttributeCount()) {
180      try {                                                  final AttributeDescriptor attributeTypeAtIdx = fs.getSchema()
181        if (map == null)                                                                  .getAttributeDescriptors().get(attrIdx);
182          setFeatureSource(null, null, null);                                                  visibleAttrNames.add(attributeTypeAtIdx.getLocalName());
183        else                                          } else {
184          setFeatureSource(map.getGeoObject(), map.getAttributeMetaDataMap(), filter);                                                  LOGGER.warn("AttributeMetaData has been found for columnIdx="+attrIdx+", but fs.getSchema().getAttributeCount() = "+fs.getSchema().getAttributeCount()+". Ignored.");
185      } catch (Exception err) {                                          }
186        throw new RuntimeException(err);                                  }
187      }  
188    }                                  // create a query for the visible attributes
189                                      String[] properties = visibleAttrNames.toArray(new String[0]);
190    /**  
191     * Resets the filter for the table.                                  LOGGER.debug("Query contains the following attributes: "
192     * @param filter a filter                                                  + visibleAttrNames);
193     */  
194    public void setFilter(Filter filter) {                                  query = new DefaultQuery(fs.getSchema().getTypeName(), filter,
195      try{                                                  properties);
196        setFeatureSource(this.featureSource, this.origAMD, filter);                          }
197      } catch (Exception err) {                          fc = fs.getFeatures(query);
198          LOGGER.error("Setting the filter of the table model", err);  
199        throw new RuntimeException(err);                          // FAILS:!!!, even with query = new
200      }                          // DefaultQuery(fs.getSchema().getTypeName(), filter);
201    }                          // java.lang.UnsupportedOperationException: Unknown feature
202                              // attribute: PQM_MOD
203    /**                          // at
204     * @return <code>Filter.INCLUDE</code> or the {@link Filter} applied to the Features                          // schmitzm.geotools.feature.FeatureOperationTree.evaluate(FeatureOperationTree.java:93)
205     */                          // bounds = fc.getBounds();
206    public Filter getFilter() {                          // SK, 17.4.2009
207            return this.filter;                          //      
208    }                          // System.out.println("Filter = "+filter);
209                            // System.out.println("Size of FC = "+fc.size());
210    /**                          // System.out.println("anz att= "+fc.getNumberOfAttributes());
211     * After calling {@code super.reorganize(.)} this method replaced the                  }
212     * column descriptions with the titles of the {@code AttributeMetaData}.                  setFeatureCollection(fc);
213     * @param fireTableStructureChanged indicates whether a table event is          }
214     *        initiated after reorganize  
215     */          /**
216    @Override           * Converts the {@code StyledFeatureCollection} to a {@code FeatureSource}
217    protected void reorganize(boolean fireTableStructureChanged) {           * and sets this as the new data source for the table.
218      super.reorganize(false);           *
219      // translate the column names           * @param fs
220      if (visibleAMD != null) {           *            the feature source
221        Iterator<Integer> keys = visibleAMD.keySet().iterator();           * @param amd
222        for (int i = 0; i < colNames.length && keys.hasNext(); i++) {           *            {@link AttributeMetaData}-Map to define the visible attributes
223          Translation title = visibleAMD.get(keys.next()).getTitle();           *            and translation
224          if (!I8NUtil.isEmpty(title)) {           */
225  //          System.out.println("set colname " + i + " to " + title.toString());          public void setFeatureCollection(StyledFeaturesInterface layer,
226            colNames[i] = title.toString();                          Filter filter) {
227          }                  this.layer = layer;
228        }                  try {
229      }                          if (layer == null)
230      if ( fireTableStructureChanged )                                  setFeatureSource(null, null, null);
231        fireTableStructureChanged();                          else {
232    }                                  FeatureCollection fc = layer.getFeatureCollection();
233                                    String fcName = fc.getSchema().getName().getLocalPart();
234    /**                                  FeatureSource fs = new MemoryDataStore(fc)
235           * @returns Cached bounds for the whole dataset (without applying the                                                  .getFeatureSource(fcName);
236           *          filter) or <code>null</code>                                  setFeatureSource(fs, layer.getAttributeMetaDataMap(), filter);
237           */                          }
238          public Envelope getBounds() {                  } catch (Exception err) {
239                  return bounds;                          throw new RuntimeException(err);
240          }                  }
241  }          }
242    
243            /**
244             * Sets the {@code StyledFeatureCollection} as new data source for the
245             * table.
246             *
247             * @param fs
248             *            the feature source
249             * @param amd
250             *            {@link AttributeMetaData}-Map to define the visible attributes
251             *            and translation
252             */
253            public void setFeatureCollection(StyledFeatureSourceInterface layer,
254                            Filter filter) {
255                    this.layer = layer;
256                    try {
257                            if (layer == null)
258                                    setFeatureSource(null, null, null);
259                            else
260                                    setFeatureSource(layer.getGeoObject(), layer
261                                                    .getAttributeMetaDataMap(), filter);
262                    } catch (Exception err) {
263                            throw new RuntimeException(err);
264                    }
265            }
266    
267            /**
268             * Resets the filter for the table.
269             *
270             * @param filter
271             *            a filter
272             */
273            public void setFilter(Filter filter) {
274                    try {
275                            setFeatureSource(this.featureSource, this.origAMD, filter);
276                    } catch (Exception err) {
277                            LOGGER.error("Setting the filter of the table model", err);
278                            throw new RuntimeException(err);
279                    }
280            }
281    
282            /**
283             * @return <code>Filter.INCLUDE</code> or the {@link Filter} applied to the
284             *         Features
285             */
286            public Filter getFilter() {
287                    return this.filter;
288            }
289    
290            /**
291             * After calling {@code super.reorganize(.)} this method replaced the column
292             * descriptions with the titles of the {@code AttributeMetaData}.
293             *
294             * @param fireTableStructureChanged
295             *            indicates whether a table event is initiated after reorganize
296             */
297            @Override
298            protected void reorganize(boolean fireTableStructureChanged) {
299                    super.reorganize(false);
300                    // translate the column names
301                    if (visibleAMD != null) {
302                            Iterator<Integer> keys = visibleAMD.keySet().iterator();
303                            for (int i = 0; i < colNames.length && keys.hasNext(); i++) {
304                                    Translation title = visibleAMD.get(keys.next()).getTitle();
305                                    if (!I8NUtil.isEmpty(title)) {
306                                            // System.out.println("set colname " + i + " to " +
307                                            // title.toString());
308                                            colNames[i] = title.toString();
309                                    }
310                            }
311                    }
312                    if (fireTableStructureChanged)
313                            fireTableStructureChanged();
314            }
315    
316            /**
317             * @return Cached bounds for the whole dataset (without applying the filter)
318             *         or <code>null</code>
319             */
320            public Envelope getBounds() {
321                    return bounds;
322            }
323    }

Legend:
Removed from v.112  
changed lines
  Added in v.335

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26