/[schmitzm]/branches/2.3.x/src/skrueger/geotools/StyledFeatureCollectionTableModel.java
ViewVC logotype

Annotation of /branches/2.3.x/src/skrueger/geotools/StyledFeatureCollectionTableModel.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1266 - (hide annotations)
Fri Nov 12 19:18:35 2010 UTC (14 years, 3 months ago) by alfonx
File size: 9938 byte(s)
Fixed an exception that appeared when column settings where changed while the table with these columns was visible. Now the attribute table will not change until it is closed and reopened.
1 alfonx 244 /*******************************************************************************
2     * Copyright (c) 2009 Martin O. J. Schmitz.
3     *
4     * This file is part of the SCHMITZM library - a collection of utility
5 alfonx 256 * classes based on Java 1.6, focusing (not only) on Java Swing
6 alfonx 244 * and the Geotools library.
7     *
8     * The SCHMITZM project is hosted at:
9     * http://wald.intevation.org/projects/schmitzm/
10     *
11     * 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     * of the License, or (at your option) any later version.
15     *
16     * This program is distributed in the hope that it will be useful,
17     * but WITHOUT ANY WARRANTY; without even the implied warranty of
18     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19     * GNU General Public License for more details.
20     *
21     * You should have received a copy of the GNU Lesser General Public License (license.txt)
22     * along with this program; if not, write to the Free Software
23     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24     * or try this link: http://www.gnu.org/licenses/lgpl.html
25     *
26     * Contributors:
27     * Martin O. J. Schmitz - initial API and implementation
28 alfonx 862 * Stefan A. Tzeggai - additional utility classes
29 alfonx 244 ******************************************************************************/
30     package skrueger.geotools;
31    
32 alfonx 534 import java.util.HashMap;
33 alfonx 1043 import java.util.LinkedHashSet;
34 alfonx 681 import java.util.List;
35 alfonx 244
36     import org.apache.log4j.Logger;
37     import org.geotools.data.DefaultQuery;
38     import org.geotools.data.FeatureSource;
39     import org.geotools.data.Query;
40     import org.geotools.feature.FeatureCollection;
41 alfonx 335 import org.opengis.feature.simple.SimpleFeature;
42     import org.opengis.feature.simple.SimpleFeatureType;
43 alfonx 332 import org.opengis.feature.type.AttributeDescriptor;
44 mojays 1033 import org.opengis.feature.type.Name;
45 alfonx 244 import org.opengis.filter.Filter;
46    
47 alfonx 534 import schmitzm.geotools.feature.FeatureUtil;
48 alfonx 244 import schmitzm.geotools.gui.FeatureCollectionTableModel;
49 alfonx 788 import skrueger.AttributeMetadataImpl;
50 alfonx 772 import skrueger.AttributeMetadataInterface;
51 alfonx 244
52     import com.vividsolutions.jts.geom.Envelope;
53    
54     /**
55     * This class extends the the {@link FeatureCollectionTableModel} with the
56 alfonx 769 * functionalities of the {@link AttributeMetadataImpl}.
57 alfonx 244 * <ul>
58     * <li>column names are translated according to
59 alfonx 769 * {@link AttributeMetadataImpl#getTitle()}</li>
60 alfonx 244 * <li>columns are hidden according to {@link AttributeMetaData#isVisible()()}</li>
61 alfonx 534 * <li>Any filter defined in the {@link StyledFeaturesInterface} will be
62     * applied.</li>
63 alfonx 244 * </ul>
64     *
65 alfonx 862 * @author Stefan A. Tzeggai
66 alfonx 244 */
67     public class StyledFeatureCollectionTableModel extends
68     FeatureCollectionTableModel {
69     final static private Logger LOGGER = Logger
70     .getLogger(StyledFeatureCollectionTableModel.class);
71 alfonx 769 /** Contains the complete {@link AttributeMetadataImpl}-Map of the styled layer. */
72 alfonx 772 protected AttributeMetadataMap<? extends AttributeMetadataInterface> amdMap = null;
73 alfonx 244 /** Holds the current filter on the table */
74     protected Filter filter = null;
75     /** Holds the Bounds for all features. Only set once during the constructor **/
76     protected Envelope bounds;
77 alfonx 534 /**
78     * Tooltips für die Spaltennamen. Wird nur beim Aufruf von
79     * {@link #reorganize} befuellt.
80     */
81     protected String[] colTooltips = null;
82 alfonx 244
83 alfonx 681 /** A cache for the #sortedValuesVisibleOnly() **/
84 alfonx 772 protected List<? extends AttributeMetadataInterface> amdMapVisibleOnly = null;
85 alfonx 681
86 alfonx 244 /**
87     * Creates a new table model for a styled layer.
88     *
89 alfonx 428 * @param styledFeatures
90 alfonx 244 * the styled layer
91     * @param filter
92     * filter applied to the table
93     */
94 alfonx 534 public StyledFeatureCollectionTableModel(
95     StyledFeaturesInterface<?> styledFeatures) {
96 alfonx 428 setStyledFeatures(styledFeatures);
97 alfonx 244 }
98    
99     /**
100 alfonx 681 * This overwritten method filters the values for NODATA-values defined in
101 alfonx 769 * the {@link AttributeMetadataImpl}
102 alfonx 681 */
103     @Override
104     public Object getValueAt(int row, int col) {
105     Object rawValue = super.getValueAt(row, col);
106 alfonx 1266 return amdMapVisibleOnly.get(col).fiterNodata(rawValue);
107 alfonx 681 }
108    
109     /**
110 alfonx 244 * Sets a new data source for the table.
111     *
112     * @param fs
113     * the feature source
114 alfonx 534 * @param amdm
115 alfonx 769 * {@link AttributeMetadataImpl}-Map to define the visible attributes
116 alfonx 244 * and translation
117     */
118 alfonx 534 protected void setFeatureSource(
119     FeatureSource<SimpleFeatureType, SimpleFeature> fs,
120 alfonx 772 AttributeMetadataMap<? extends AttributeMetadataInterface> amdm, Filter filter) throws Exception {
121 alfonx 534
122 alfonx 244 if (filter == null)
123     filter = Filter.INCLUDE;
124    
125 alfonx 534 // this.featureSource = fs;
126 alfonx 244 this.filter = filter;
127 alfonx 534 this.amdMap = amdm;
128 alfonx 681 this.amdMapVisibleOnly = amdMap.sortedValuesVisibleOnly();
129 alfonx 244
130 alfonx 428 FeatureCollection<SimpleFeatureType, SimpleFeature> fc = null;
131 alfonx 244 if (fs != null) {
132    
133     bounds = fs.getBounds();
134    
135 alfonx 464 final SimpleFeatureType schema = fs.getSchema();
136     Query query = new DefaultQuery(schema.getTypeName(), filter);
137 alfonx 534 if (amdm != null) {
138 alfonx 1043 LinkedHashSet<String> visibleAttrNames = new LinkedHashSet<String>();
139 alfonx 534
140 alfonx 607 // Add the column with the geometry (usually "the_geom") always
141 alfonx 534 visibleAttrNames.add(schema.getGeometryDescriptor()
142     .getLocalName());
143    
144     // Add other visible attributes as ordered by weights
145 alfonx 772 for (AttributeMetadataInterface a : amdMapVisibleOnly) {
146 alfonx 534 visibleAttrNames.add(a.getLocalName());
147 alfonx 244 }
148    
149 alfonx 681 // Tested with 2.6.x trunk from 2009-11-26 and it now works. So
150     // we only request the properties we need!
151     // /**
152     // * I got NPEs when properties contained only [the_geom]
153     // ?!??!!??
154     // */
155     // if (properties.length > 1) {
156     query = new DefaultQuery(schema.getTypeName(), filter,
157     visibleAttrNames.toArray(new String[] {}));
158     // } else {
159     // query = new DefaultQuery(schema.getTypeName(), filter);
160     // }
161 alfonx 244 }
162     fc = fs.getFeatures(query);
163     }
164     setFeatureCollection(fc);
165     }
166    
167     /**
168     * Converts the {@code StyledFeatureCollection} to a {@code FeatureSource}
169     * and sets this as the new data source for the table.
170     *
171     * @param fs
172     * the feature source
173     * @param amd
174 alfonx 769 * {@link AttributeMetadataImpl}-Map to define the visible attributes
175 alfonx 244 * and translation
176     */
177 alfonx 428 public void setStyledFeatures(StyledFeaturesInterface<?> styledFeatures) {
178 alfonx 244 try {
179 alfonx 428 if (styledFeatures == null)
180 alfonx 244 setFeatureSource(null, null, null);
181     else {
182 alfonx 534 setFeatureSource(styledFeatures.getFeatureSource(),
183     styledFeatures.getAttributeMetaDataMap(),
184     styledFeatures.getFilter());
185 alfonx 244 }
186     } catch (Exception err) {
187     throw new RuntimeException(err);
188     }
189     }
190    
191     /**
192     * After calling {@code super.reorganize(.)} this method replaced the column
193     * descriptions with the titles of the {@code AttributeMetaData}.
194     *
195     * @param fireTableStructureChanged
196     * indicates whether a table event is initiated after reorganize
197     */
198     @Override
199     protected void reorganize(boolean fireTableStructureChanged) {
200 alfonx 534
201     featureArray = FeatureUtil.featuresToArray(featureTable);
202     if (featureArray == null || featureArray.length == 0) {
203     colNames = new String[0];
204     colTooltips = new String[0]; // Only set and used in
205 alfonx 681 // StyledFeatureCollectionTableModel
206 alfonx 534 colClass = new Class[0];
207     } else {
208     // Struktur der Tabelle vom AttributeMetaDtaaMap übernehmen
209     SimpleFeatureType schema = featureArray[0].getFeatureType();
210     // Pruefen, welche Attribute angezeigt werden
211     attrTypes.clear();
212 alfonx 772 for (AttributeMetadataInterface amd : amdMapVisibleOnly) {
213 mojays 1033 Name name = amd.getName();
214     AttributeDescriptor type = schema.getDescriptor(name);
215     // if type can not be determined by complete name,
216     // try only the local name
217     if ( type == null )
218     type = schema.getDescriptor(name.getLocalPart());
219 alfonx 534 if (attrFilter == null || attrFilter.accept(type))
220     attrTypes.add(type);
221     }
222     // Namen und Attribut-Indizes der angezeigten Spalten ermitteln
223     colNames = new String[attrTypes.size()];
224     colTooltips = new String[attrTypes.size()]; // Only set and used in
225 alfonx 681 // StyledFeatureCollectionTableModel
226 alfonx 534 colClass = new Class[attrTypes.size()];
227     attrIdxForCol = new int[attrTypes.size()];
228 alfonx 464 for (int i = 0; i < colNames.length; i++) {
229 mojays 1033 Name name = amdMapVisibleOnly.get(i).getName();
230     AttributeDescriptor descriptor = schema.getDescriptor(name);
231     // if type can not be determined by complete name,
232     // try only the local name
233     if ( descriptor == null )
234     descriptor = schema.getDescriptor(name.getLocalPart());
235 alfonx 534
236     // Not so nice in 26: find the index of an attribute...
237     int idx = schema.getAttributeDescriptors().indexOf(descriptor);
238     attrIdxForCol[i] = idx;
239    
240     String attName = schema.getAttributeDescriptors().get(idx)
241     .getLocalName();
242     colNames[i] = amdMap.get(attName).getTitle().toString();
243 alfonx 772 AttributeMetadataInterface amd = amdMap.get(attName);
244 alfonx 681 colTooltips[i] = "<html>" + amd.getDesc().toString() + "<br>"
245     + amd.getName() + "</html>";
246     colClass[i] = schema.getAttributeDescriptors().get(idx)
247     .getType().getBinding();
248 alfonx 244 }
249     }
250 alfonx 534
251     // store feature indexes in HashMap to optimize findFeature(.)
252     featureIdx = new HashMap<String, Integer>();
253     for (int i = 0; i < featureArray.length; i++)
254     if (featureArray[i] != null)
255     featureIdx.put(featureArray[i].getID(), i);
256 alfonx 681 //
257     // // translate the column names
258     // if (amdMap != null) {
259     // for (int i = 0; i < colNames.length; i++) {
260     // colTooltips[i] = amdMap.get(colNames[i]).getDesc().toString()
261     // + "<br>" + colNames[i];
262     // colNames[i] = amdMap.get(colNames[i]).getTitle().toString();
263     //
264     // }
265     // }
266 alfonx 244 if (fireTableStructureChanged)
267     fireTableStructureChanged();
268 alfonx 534
269 alfonx 244 }
270    
271     /**
272     * @return Cached bounds for the whole dataset (without applying the filter)
273     * or <code>null</code>
274     */
275     public Envelope getBounds() {
276     return bounds;
277     }
278     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26