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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1265 - (show 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 /*******************************************************************************
2 * Copyright (c) 2009 Martin O. J. Schmitz.
3 *
4 * This file is part of the SCHMITZM library - a collection of utility
5 * classes based on Java 1.6, focusing (not only) on Java Swing
6 * 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 * Stefan A. Tzeggai - additional utility classes
29 ******************************************************************************/
30 package skrueger.geotools;
31
32 import java.util.HashMap;
33 import java.util.LinkedHashSet;
34 import java.util.List;
35
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 import org.opengis.feature.simple.SimpleFeature;
42 import org.opengis.feature.simple.SimpleFeatureType;
43 import org.opengis.feature.type.AttributeDescriptor;
44 import org.opengis.feature.type.Name;
45 import org.opengis.filter.Filter;
46
47 import schmitzm.geotools.feature.FeatureUtil;
48 import schmitzm.geotools.gui.FeatureCollectionTableModel;
49 import skrueger.AttributeMetadataImpl;
50 import skrueger.AttributeMetadataInterface;
51
52 import com.vividsolutions.jts.geom.Envelope;
53
54 /**
55 * This class extends the the {@link FeatureCollectionTableModel} with the
56 * functionalities of the {@link AttributeMetadataImpl}.
57 * <ul>
58 * <li>column names are translated according to
59 * {@link AttributeMetadataImpl#getTitle()}</li>
60 * <li>columns are hidden according to {@link AttributeMetaData#isVisible()()}</li>
61 * <li>Any filter defined in the {@link StyledFeaturesInterface} will be
62 * applied.</li>
63 * </ul>
64 *
65 * @author Stefan A. Tzeggai
66 */
67 public class StyledFeatureCollectionTableModel extends
68 FeatureCollectionTableModel {
69 final static private Logger LOGGER = Logger
70 .getLogger(StyledFeatureCollectionTableModel.class);
71 /**
72 * Contains the complete {@link AttributeMetadataImpl}-Map of the styled
73 * layer.
74 */
75 protected AttributeMetadataMap<? extends AttributeMetadataInterface> amdMap = null;
76 /** 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 /**
81 * Tooltips für die Spaltennamen. Wird nur beim Aufruf von
82 * {@link #reorganize} befuellt.
83 */
84 protected String[] colTooltips = null;
85
86 /**
87 * A cache for the #sortedValuesVisibleOnly(). WHen the amd is changed
88 * externally, this object will stay the same
89 **/
90 protected List<? extends AttributeMetadataInterface> amdMapVisibleOnly = null;
91
92 /**
93 * Creates a new table model for a styled layer.
94 *
95 * @param styledFeatures
96 * the styled layer
97 * @param filter
98 * filter applied to the table
99 */
100 public StyledFeatureCollectionTableModel(
101 StyledFeaturesInterface<?> styledFeatures) {
102 setStyledFeatures(styledFeatures);
103 }
104
105 /**
106 * This overwritten method filters the values for NODATA-values defined in
107 * the {@link AttributeMetadataImpl}
108 */
109 @Override
110 public Object getValueAt(int row, int col) {
111 Object rawValue = super.getValueAt(row, col);
112 return amdMapVisibleOnly.get(col).fiterNodata(rawValue);
113 }
114
115 /**
116 * Sets a new data source for the table.
117 *
118 * @param fs
119 * the feature source
120 * @param amdm
121 * {@link AttributeMetadataImpl}-Map to define the visible
122 * attributes and translation
123 */
124 protected void setFeatureSource(
125 FeatureSource<SimpleFeatureType, SimpleFeature> fs,
126 AttributeMetadataMap<? extends AttributeMetadataInterface> amdm,
127 Filter filter) throws Exception {
128
129 if (filter == null)
130 filter = Filter.INCLUDE;
131
132 // this.featureSource = fs;
133 this.filter = filter;
134 this.amdMap = amdm;
135 this.amdMapVisibleOnly = amdMap.sortedValuesVisibleOnly();
136
137 FeatureCollection<SimpleFeatureType, SimpleFeature> fc = null;
138 if (fs != null) {
139
140 bounds = fs.getBounds();
141
142 final SimpleFeatureType schema = fs.getSchema();
143 Query query = new DefaultQuery(schema.getTypeName(), filter);
144 if (amdm != null) {
145 LinkedHashSet<String> visibleAttrNames = new LinkedHashSet<String>();
146
147 // Add the column with the geometry (usually "the_geom") always
148 visibleAttrNames.add(schema.getGeometryDescriptor()
149 .getLocalName());
150
151 // Add other visible attributes as ordered by weights
152 for (AttributeMetadataInterface a : amdMapVisibleOnly) {
153 visibleAttrNames.add(a.getLocalName());
154 }
155
156 // 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 }
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 * {@link AttributeMetadataImpl}-Map to define the visible
182 * attributes and translation
183 */
184 public void setStyledFeatures(StyledFeaturesInterface<?> styledFeatures) {
185 try {
186 if (styledFeatures == null)
187 setFeatureSource(null, null, null);
188 else {
189 setFeatureSource(styledFeatures.getFeatureSource(),
190 styledFeatures.getAttributeMetaDataMap(),
191 styledFeatures.getFilter());
192 }
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
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 // StyledFeatureCollectionTableModel
213 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 for (AttributeMetadataInterface amd : amdMapVisibleOnly) {
220 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 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 // StyledFeatureCollectionTableModel
233 colClass = new Class[attrTypes.size()];
234 attrIdxForCol = new int[attrTypes.size()];
235 for (int i = 0; i < colNames.length; i++) {
236 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
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 AttributeMetadataInterface amd = amdMap.get(attName);
251 colTooltips[i] = "<html>" + amd.getDesc().toString() + "<br>"
252 + amd.getName() + "</html>";
253 colClass[i] = schema.getAttributeDescriptors().get(idx)
254 .getType().getBinding();
255 }
256 }
257
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 //
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 if (fireTableStructureChanged)
274 fireTableStructureChanged();
275
276 }
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