/[schmitzm]/branches/2.0-RC2/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java
ViewVC logotype

Contents of /branches/2.0-RC2/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 162 - (show annotations)
Mon Jun 22 21:05:20 2009 UTC (15 years, 8 months ago) by alfonx
Original Path: trunk/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java
File MIME type: text/plain
File size: 11337 byte(s)
* FINALLY! FINALLY! Found the regressoin in GT 2.4.5 that had made AtlasStyler very buggy. An setSize(Expression.NIL) is set in StyleFactoryImpl which was evil, because NILExpressions are only supported properly in 2.5. So i overwrite the class in schmitzm and changed the one line. Then i was also able to remove a few workarounds that were not needed anymore. 
* Some more fixed in AtlasStyler, like: Local symbols are only shown one now.. not twice.

Next commit will be a full build with all JARs
1 /**
2 Copyright 2008 Stefan Alfons Krüger
3
4 atlas-framework - This file is part of the Atlas Framework
5
6 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.
7 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.
8 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
9
10 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.
11 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.
12 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.
13 **/
14 package skrueger.geotools.selection;
15
16 import java.beans.PropertyChangeEvent;
17 import java.beans.PropertyChangeListener;
18 import java.util.Arrays;
19 import java.util.Collection;
20 import java.util.HashSet;
21 import java.util.Set;
22 import java.util.Vector;
23
24 import javax.swing.JTable;
25 import javax.swing.ListSelectionModel;
26 import javax.swing.event.ListSelectionListener;
27
28 import org.geotools.feature.Feature;
29 import org.geotools.map.MapLayer;
30 import org.geotools.styling.FeatureTypeStyle;
31 import org.geotools.styling.Style;
32 import org.opengis.filter.identity.FeatureId;
33
34 import schmitzm.geotools.FilterUtil;
35 import schmitzm.geotools.gui.JMapPane;
36 import schmitzm.geotools.map.event.FeatureSelectedEvent;
37 import schmitzm.geotools.map.event.JMapPaneEvent;
38 import schmitzm.geotools.map.event.JMapPaneListener;
39 import schmitzm.geotools.styling.StylingUtil;
40 import schmitzm.lang.LangUtil;
41 import skrueger.geotools.MapPaneToolBar;
42 import skrueger.geotools.StyledMapInterface;
43
44 /**
45 * This class keeps the selection of a (feature) {@link JTable} synchronized
46 * with the {@link StyledLayerSelectionModel} of a layer. This is done by
47 * implementing:
48 * <ul>
49 * <li>a {@link PropertyChangeListener} which listens to the
50 * {@link StyledLayerSelectionModel} and accordingly changes the {@link JTable}
51 * selection</li>
52 * <li>a {@link ListSelectionListener} which listens to the {@link JTable} and
53 * accordingly changes the {@link StyledLayerSelectionModel} selection</li>
54 * </ul>
55 * After creating, the instance of this synchronizer must be added as listener
56 * to both, the {@link StyledLayerSelectionModel} and the table's
57 * {@link ListSelectionModel}.
58 *
59 * @author <a href="mailto:[email protected]">Martin Schmitz</a>
60 * (University of Bonn/Germany)
61 */
62 public class FeatureMapLayerSelectionSynchronizer extends
63 StyledLayerSelectionModelSynchronizer<StyledFeatureLayerSelectionModel>
64 implements JMapPaneListener {
65 public static final String SELECTION_STYLING = "SELECTION";
66 /**
67 * Holds the {@link MapLayer} to keep synchronized with the layer selection
68 * model.
69 */
70 protected final MapLayer mapLayer;
71 protected final StyledMapInterface<?> styledMapLayer;
72 protected final JMapPane mapPane;
73 private final MapPaneToolBar toolBar;
74
75 /**
76 * Creates a new synchronizer
77 *
78 * @param layerSelModel
79 * layer selection model to keep synchronized with the
80 * {@link MapLayer}
81 *
82 * @param mapLayer
83 * {@link MapLayer} to keep synchronized with.
84 */
85 public FeatureMapLayerSelectionSynchronizer(
86 StyledFeatureLayerSelectionModel layerSelModel,
87 StyledMapInterface<?> styledMapLayer, MapLayer mapLayer,
88 JMapPane mapPane, MapPaneToolBar toolBar) {
89
90 super(layerSelModel);
91 this.styledMapLayer = styledMapLayer;
92
93 this.mapLayer = mapLayer;
94 this.mapPane = mapPane;
95 this.toolBar = toolBar;
96 }
97
98 /**
99 * Called by {@link StyledLayerSelectionModel} when a the selection on other
100 * selection components (map, chart, ...) has changed. When calling this
101 *
102 * method changes the {@link MapLayer} selection according to the
103 * {@link StyledLayerSelectionModel} selection.
104 *
105 * @param evt
106 * an event
107 */
108 @Override
109 public void propertyChange(PropertyChangeEvent evt) {
110
111 if (!isEnabled())
112 return;
113
114 if (!(evt instanceof StyledLayerSelectionEvent))
115 return;
116 StyledLayerSelectionEvent selEvt = (StyledLayerSelectionEvent) evt;
117 // Only react on own layer and ignore events invoked by
118 // this component itself
119 if (selEvt.getEmitter() != layerSelModel || selectionChangeCausedByMe)
120 return;
121 // Apply new selection on table (except this event is one of
122 // some more events)
123 Vector<String> newSelection = layerSelModel.getSelection();
124 if (newSelection == null)
125 return;
126
127 // Avoid event circles in valueChanged(..)
128 selectionChangeCausedByMe = true;
129
130 changeLayerStyle(newSelection);
131
132 // Danger of event circles in valueChanged(..) banned
133 selectionChangeCausedByMe = false;
134 }
135
136 /**
137 * Changes the Style of the {@link MapLayer} to reflect changes of the
138 * selection.
139 *
140 * @param newSelection
141 * A {@link Vector} of Feature-IDs that are selected.
142 */
143 private void changeLayerStyle(final Vector<String> newSelection) {
144 Style selectionMapStyle = null;
145 try {
146 if (newSelection.isEmpty()) {
147
148 selectionMapStyle = styledMapLayer.getStyle();
149 // LOGGER.debug("NO SELECTION .. set to original style directly");
150
151 } else {
152 LOGGER.debug("SELECTION .. change style");
153
154 // We take Style from the MapLayer that is displayed at the
155 // moment. We do not use the styledMapLayer.getStyle, because in
156 // the atlas, this always return the default style, but
157 // additionaly styles might be selected.
158 // Taking the style from the mapLayer indicated, that we have to
159 // remove any selection rules first.
160 Style originalStyle = mapLayer.getStyle();
161
162 // TODO The default style is not good here. We need
163 // .createSelectionStyle(normalStyle, geoObj);
164 selectionMapStyle = StylingUtil
165 .createSelectionStyle(styledMapLayer.getGeoObject());
166 // selectionMapStyle = StylingUtil
167 // .createDefaultStyle(styledMapLayer.getGeoObject());
168
169 selectionMapStyle.getFeatureTypeStyles()[0]
170 .setName(SELECTION_STYLING);
171
172 /**
173 *
174 * Add a Filter to the selectionMapStyle, so that it is only
175 * used on objects that are selected. <br/>
176 *
177 * Note 1:<br/>
178 * It is NEVER allowed to GeoTools extend Filter () { .. } (and write
179 * tests into the evaluate block). Especially for the
180 * ShapeFileRenderer, we may only use a geotools Filter.<br/>
181 *
182 * Note 2:<br/>
183 * The FilterUtil.FILTER_FAC2.id(fids) wants a set of FeatureId-Objects!
184 */
185
186 Set<FeatureId> fids = new HashSet<FeatureId>();
187 for (String fid : newSelection) {
188 fids.add(FilterUtil.FILTER_FAC2.featureId(fid));
189 }
190
191 selectionMapStyle.getFeatureTypeStyles()[0].getRules()[0]
192 .setFilter(FilterUtil.FILTER_FAC2.id(fids));
193
194 FeatureTypeStyle[] originalFeatureTypeStyles = originalStyle
195 .getFeatureTypeStyles();
196 FeatureTypeStyle[] newFeatureTypes;
197 if (originalFeatureTypeStyles[originalFeatureTypeStyles.length - 1]
198 .getName() != null
199 && originalFeatureTypeStyles[originalFeatureTypeStyles.length - 1]
200 .getName().equals(SELECTION_STYLING)) {
201 newFeatureTypes = Arrays.copyOf(originalFeatureTypeStyles,
202 originalFeatureTypeStyles.length - 1);
203 } else {
204 newFeatureTypes = originalFeatureTypeStyles;
205 }
206
207 // The last FTS is the selection FTS
208 newFeatureTypes = LangUtil.extendArray(newFeatureTypes,
209 selectionMapStyle.getFeatureTypeStyles());
210
211 selectionMapStyle.setFeatureTypeStyles(newFeatureTypes);
212
213 }
214
215 mapLayer.setStyle(selectionMapStyle);
216 mapPane.refresh();
217 } catch (Exception e) {
218 LOGGER.error("Error while trying to create a selection style", e);
219 }
220 }
221
222 /**
223 * Used to synchronize {@link FeatureSelectedEvent}s with the
224 * {@link StyledFeatureLayerSelectionModel}
225 */
226 @Override
227 public void performMapPaneEvent(JMapPaneEvent e) {
228
229 // Ignore event if it is caused by us or the synchronizer is disabled.
230 if (!isEnabled() || selectionChangeCausedByMe)
231 return;
232
233 if (!(e instanceof FeatureSelectedEvent)) {
234 // LOGGER.debug("Ignoring event " + e);
235 return;
236 }
237
238 /**
239 * Only listen to FeatureSelectedEvents if an appropriate tool is
240 * selected.
241 */
242 final int selectedTool = toolBar.getSelectedTool();
243 if (selectedTool != MapPaneToolBar.TOOL_SELECTION_ADD
244 && selectedTool != MapPaneToolBar.TOOL_SELECTION_REMOVE
245 && selectedTool != MapPaneToolBar.TOOL_SELECTION_SET) {
246 return;
247 }
248
249 // only listen to events directly coming from JMapPane
250 // selection (ignore selections from FilterDialog)
251 if (e.getSourceObject() != this.mapPane)
252 return;
253
254 FeatureSelectedEvent fse = (FeatureSelectedEvent) e;
255
256 /**
257 * Checking, that the FeatureSelectedEvent actually contains features
258 * from this layer
259 */
260 final String sourceID = fse.getSourceLayer().getTitle();
261 final String syncForID = mapLayer.getTitle();
262 if (sourceID != null && syncForID != null
263 && !sourceID.equals(syncForID)) {
264 LOGGER.debug("Ignoring a FeatureSelectedEvent from " + sourceID);
265 return;
266 }
267
268 LOGGER.debug("do event " + fse);
269
270 // Avoid event circles in propertyChange(..)
271 selectionChangeCausedByMe = true;
272
273 Collection<Feature> selectionResult = (Collection<Feature>) fse
274 .getSelectionResult();
275
276 // reset the selection of the DpLayerSelectionModel
277 // layerSelModel.setValueIsAdjusting(true);
278
279 if (selectedTool == MapPaneToolBar.TOOL_SELECTION_ADD) {
280 layerSelModel.setValueIsAdjusting(true);
281 for (Feature f : selectionResult) {
282 layerSelModel.addSelection(f.getID());
283 }
284 layerSelModel.setValueIsAdjusting(false);
285 } else if (selectedTool == MapPaneToolBar.TOOL_SELECTION_SET) {
286 layerSelModel.setValueIsAdjusting(true);
287 layerSelModel.clearSelection();
288
289 for (Feature f : selectionResult) {
290 layerSelModel.addSelection(f.getID());
291 }
292
293 LOGGER.debug("Setting selection to " + selectionResult.size());
294 layerSelModel.setValueIsAdjusting(false);
295 } else if (selectedTool == MapPaneToolBar.TOOL_SELECTION_REMOVE) {
296 layerSelModel.setValueIsAdjusting(true);
297 for (Feature f : selectionResult) {
298 layerSelModel.removeSelection(f.getID());
299 }
300 layerSelModel.setValueIsAdjusting(false);
301 }
302
303 // Show selected features in the map, which is not automatically done by
304 // the origin: FeatureSelectedEvent
305 changeLayerStyle(layerSelModel.getSelection());
306
307 // Danger of event circles in propertyChange(..) banned
308 selectionChangeCausedByMe = false;
309 }
310
311 }

Properties

Name Value
svn:eol-style native
svn:keywords Id
svn:mime-type text/plain

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26