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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1265 - (hide annotations)
Fri Nov 12 19:17:47 2010 UTC (14 years, 3 months ago) by alfonx
File size: 9878 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 1265 /**
72     * Contains the complete {@link AttributeMetadataImpl}-Map of the styled
73     * layer.
74     */
75 alfonx 772 protected AttributeMetadataMap<? extends AttributeMetadataInterface> amdMap = null;
76 alfonx 244 /** Holds the current filter on the table */
77     protected Filter filter = null;
78     /** Holds the Bounds for all features. Only set once during the constructor **/
79     protected Envelope bounds;
80 alfonx 534 /**
81     * Tooltips für die Spaltennamen. Wird nur beim Aufruf von
82     * {@link #reorganize} befuellt.
83     */
84     protected String[] colTooltips = null;
85 alfonx 244
86 alfonx 1265 /**
87     * A cache for the #sortedValuesVisibleOnly(). WHen the amd is changed
88     * externally, this object will stay the same
89     **/
90 alfonx 772 protected List<? extends AttributeMetadataInterface> amdMapVisibleOnly = null;
91 alfonx 681
92 alfonx 244 /**
93     * Creates a new table model for a styled layer.
94     *
95 alfonx 428 * @param styledFeatures
96 alfonx 244 * the styled layer
97     * @param filter
98     * filter applied to the table
99     */
100 alfonx 534 public StyledFeatureCollectionTableModel(
101     StyledFeaturesInterface<?> styledFeatures) {
102 alfonx 428 setStyledFeatures(styledFeatures);
103 alfonx 244 }
104    
105     /**
106 alfonx 681 * This overwritten method filters the values for NODATA-values defined in
107 alfonx 769 * the {@link AttributeMetadataImpl}
108 alfonx 681 */
109     @Override
110     public Object getValueAt(int row, int col) {
111     Object rawValue = super.getValueAt(row, col);
112 alfonx 1265 return amdMapVisibleOnly.get(col).fiterNodata(rawValue);
113 alfonx 681 }
114 alfonx 1265
115 alfonx 681 /**
116 alfonx 244 * Sets a new data source for the table.
117     *
118     * @param fs
119     * the feature source
120 alfonx 534 * @param amdm
121 alfonx 1265 * {@link AttributeMetadataImpl}-Map to define the visible
122     * attributes and translation
123 alfonx 244 */
124 alfonx 534 protected void setFeatureSource(
125     FeatureSource<SimpleFeatureType, SimpleFeature> fs,
126 alfonx 1265 AttributeMetadataMap<? extends AttributeMetadataInterface> amdm,
127     Filter filter) throws Exception {
128 alfonx 534
129 alfonx 244 if (filter == null)
130     filter = Filter.INCLUDE;
131    
132 alfonx 534 // this.featureSource = fs;
133 alfonx 244 this.filter = filter;
134 alfonx 534 this.amdMap = amdm;
135 alfonx 681 this.amdMapVisibleOnly = amdMap.sortedValuesVisibleOnly();
136 alfonx 244
137 alfonx 428 FeatureCollection<SimpleFeatureType, SimpleFeature> fc = null;
138 alfonx 244 if (fs != null) {
139    
140     bounds = fs.getBounds();
141    
142 alfonx 464 final SimpleFeatureType schema = fs.getSchema();
143     Query query = new DefaultQuery(schema.getTypeName(), filter);
144 alfonx 534 if (amdm != null) {
145 alfonx 1043 LinkedHashSet<String> visibleAttrNames = new LinkedHashSet<String>();
146 alfonx 534
147 alfonx 607 // Add the column with the geometry (usually "the_geom") always
148 alfonx 534 visibleAttrNames.add(schema.getGeometryDescriptor()
149     .getLocalName());
150    
151     // Add other visible attributes as ordered by weights
152 alfonx 772 for (AttributeMetadataInterface a : amdMapVisibleOnly) {
153 alfonx 534 visibleAttrNames.add(a.getLocalName());
154 alfonx 244 }
155    
156 alfonx 681 // Tested with 2.6.x trunk from 2009-11-26 and it now works. So
157     // we only request the properties we need!
158     // /**
159     // * I got NPEs when properties contained only [the_geom]
160     // ?!??!!??
161     // */
162     // if (properties.length > 1) {
163     query = new DefaultQuery(schema.getTypeName(), filter,
164     visibleAttrNames.toArray(new String[] {}));
165     // } else {
166     // query = new DefaultQuery(schema.getTypeName(), filter);
167     // }
168 alfonx 244 }
169     fc = fs.getFeatures(query);
170     }
171     setFeatureCollection(fc);
172     }
173    
174     /**
175     * Converts the {@code StyledFeatureCollection} to a {@code FeatureSource}
176     * and sets this as the new data source for the table.
177     *
178     * @param fs
179     * the feature source
180     * @param amd
181 alfonx 1265 * {@link AttributeMetadataImpl}-Map to define the visible
182     * attributes and translation
183 alfonx 244 */
184 alfonx 428 public void setStyledFeatures(StyledFeaturesInterface<?> styledFeatures) {
185 alfonx 244 try {
186 alfonx 428 if (styledFeatures == null)
187 alfonx 244 setFeatureSource(null, null, null);
188     else {
189 alfonx 534 setFeatureSource(styledFeatures.getFeatureSource(),
190     styledFeatures.getAttributeMetaDataMap(),
191     styledFeatures.getFilter());
192 alfonx 244 }
193     } catch (Exception err) {
194     throw new RuntimeException(err);
195     }
196     }
197    
198     /**
199     * After calling {@code super.reorganize(.)} this method replaced the column
200     * descriptions with the titles of the {@code AttributeMetaData}.
201     *
202     * @param fireTableStructureChanged
203     * indicates whether a table event is initiated after reorganize
204     */
205     @Override
206     protected void reorganize(boolean fireTableStructureChanged) {
207 alfonx 534
208     featureArray = FeatureUtil.featuresToArray(featureTable);
209     if (featureArray == null || featureArray.length == 0) {
210     colNames = new String[0];
211     colTooltips = new String[0]; // Only set and used in
212 alfonx 681 // StyledFeatureCollectionTableModel
213 alfonx 534 colClass = new Class[0];
214     } else {
215     // Struktur der Tabelle vom AttributeMetaDtaaMap übernehmen
216     SimpleFeatureType schema = featureArray[0].getFeatureType();
217     // Pruefen, welche Attribute angezeigt werden
218     attrTypes.clear();
219 alfonx 772 for (AttributeMetadataInterface amd : amdMapVisibleOnly) {
220 alfonx 1265 Name name = amd.getName();
221     AttributeDescriptor type = schema.getDescriptor(name);
222     // if type can not be determined by complete name,
223     // try only the local name
224     if (type == null)
225     type = schema.getDescriptor(name.getLocalPart());
226 alfonx 534 if (attrFilter == null || attrFilter.accept(type))
227     attrTypes.add(type);
228     }
229     // Namen und Attribut-Indizes der angezeigten Spalten ermitteln
230     colNames = new String[attrTypes.size()];
231     colTooltips = new String[attrTypes.size()]; // Only set and used in
232 alfonx 681 // StyledFeatureCollectionTableModel
233 alfonx 534 colClass = new Class[attrTypes.size()];
234     attrIdxForCol = new int[attrTypes.size()];
235 alfonx 464 for (int i = 0; i < colNames.length; i++) {
236 alfonx 1265 Name name = amdMapVisibleOnly.get(i).getName();
237     AttributeDescriptor descriptor = schema.getDescriptor(name);
238     // if type can not be determined by complete name,
239     // try only the local name
240     if (descriptor == null)
241     descriptor = schema.getDescriptor(name.getLocalPart());
242 alfonx 534
243     // Not so nice in 26: find the index of an attribute...
244     int idx = schema.getAttributeDescriptors().indexOf(descriptor);
245     attrIdxForCol[i] = idx;
246    
247     String attName = schema.getAttributeDescriptors().get(idx)
248     .getLocalName();
249     colNames[i] = amdMap.get(attName).getTitle().toString();
250 alfonx 772 AttributeMetadataInterface amd = amdMap.get(attName);
251 alfonx 681 colTooltips[i] = "<html>" + amd.getDesc().toString() + "<br>"
252     + amd.getName() + "</html>";
253     colClass[i] = schema.getAttributeDescriptors().get(idx)
254     .getType().getBinding();
255 alfonx 244 }
256     }
257 alfonx 534
258     // store feature indexes in HashMap to optimize findFeature(.)
259     featureIdx = new HashMap<String, Integer>();
260     for (int i = 0; i < featureArray.length; i++)
261     if (featureArray[i] != null)
262     featureIdx.put(featureArray[i].getID(), i);
263 alfonx 681 //
264     // // translate the column names
265     // if (amdMap != null) {
266     // for (int i = 0; i < colNames.length; i++) {
267     // colTooltips[i] = amdMap.get(colNames[i]).getDesc().toString()
268     // + "<br>" + colNames[i];
269     // colNames[i] = amdMap.get(colNames[i]).getTitle().toString();
270     //
271     // }
272     // }
273 alfonx 244 if (fireTableStructureChanged)
274     fireTableStructureChanged();
275 alfonx 534
276 alfonx 244 }
277    
278     /**
279     * @return Cached bounds for the whole dataset (without applying the filter)
280     * or <code>null</code>
281     */
282     public Envelope getBounds() {
283     return bounds;
284     }
285     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26