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

Annotation of /branches/2.0-GP14/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 162 - (hide 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 alfonx 97 /**
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 alfonx 123 import java.util.Arrays;
19 alfonx 97 import java.util.Collection;
20 alfonx 158 import java.util.HashSet;
21     import java.util.Set;
22 alfonx 97 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 alfonx 123 import org.geotools.styling.FeatureTypeStyle;
31 alfonx 97 import org.geotools.styling.Style;
32 alfonx 158 import org.opengis.filter.identity.FeatureId;
33 alfonx 97
34 alfonx 158 import schmitzm.geotools.FilterUtil;
35 alfonx 97 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 alfonx 104 import schmitzm.lang.LangUtil;
41 alfonx 111 import skrueger.geotools.MapPaneToolBar;
42 alfonx 97 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 alfonx 106 StyledLayerSelectionModelSynchronizer<StyledFeatureLayerSelectionModel>
64     implements JMapPaneListener {
65 alfonx 111 public static final String SELECTION_STYLING = "SELECTION";
66 alfonx 97 /**
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 alfonx 111 private final MapPaneToolBar toolBar;
74 alfonx 97
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 alfonx 111 JMapPane mapPane, MapPaneToolBar toolBar) {
89 alfonx 97
90     super(layerSelModel);
91     this.styledMapLayer = styledMapLayer;
92    
93     this.mapLayer = mapLayer;
94     this.mapPane = mapPane;
95 alfonx 111 this.toolBar = toolBar;
96 alfonx 97 }
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 alfonx 151
111     if (!isEnabled())
112     return;
113    
114 alfonx 97 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 alfonx 111 Vector<String> newSelection = layerSelModel.getSelection();
124 alfonx 97 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 alfonx 151 /**
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 alfonx 111 private void changeLayerStyle(final Vector<String> newSelection) {
144 alfonx 97 Style selectionMapStyle = null;
145     try {
146     if (newSelection.isEmpty()) {
147    
148     selectionMapStyle = styledMapLayer.getStyle();
149 alfonx 151 // LOGGER.debug("NO SELECTION .. set to original style directly");
150 alfonx 106
151 alfonx 97 } else {
152 alfonx 100 LOGGER.debug("SELECTION .. change style");
153 alfonx 106
154 alfonx 123 // 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 alfonx 125 // remove any selection rules first.
160 alfonx 123 Style originalStyle = mapLayer.getStyle();
161 alfonx 101
162 alfonx 123 // TODO The default style is not good here. We need
163     // .createSelectionStyle(normalStyle, geoObj);
164 alfonx 107 selectionMapStyle = StylingUtil
165 alfonx 128 .createSelectionStyle(styledMapLayer.getGeoObject());
166 alfonx 151 // selectionMapStyle = StylingUtil
167     // .createDefaultStyle(styledMapLayer.getGeoObject());
168 alfonx 106
169 alfonx 123 selectionMapStyle.getFeatureTypeStyles()[0]
170     .setName(SELECTION_STYLING);
171    
172 alfonx 158 /**
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 alfonx 106
186 alfonx 158 Set<FeatureId> fids = new HashSet<FeatureId>();
187     for (String fid : newSelection) {
188     fids.add(FilterUtil.FILTER_FAC2.featureId(fid));
189     }
190 alfonx 106
191 alfonx 158 selectionMapStyle.getFeatureTypeStyles()[0].getRules()[0]
192     .setFilter(FilterUtil.FILTER_FAC2.id(fids));
193 alfonx 106
194 alfonx 125 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 alfonx 123 } else {
204     newFeatureTypes = originalFeatureTypeStyles;
205     }
206 alfonx 151
207 alfonx 123 // The last FTS is the selection FTS
208 alfonx 125 newFeatureTypes = LangUtil.extendArray(newFeatureTypes,
209     selectionMapStyle.getFeatureTypeStyles());
210    
211 alfonx 123 selectionMapStyle.setFeatureTypeStyles(newFeatureTypes);
212 alfonx 106
213 alfonx 97 }
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 alfonx 151 /**
223     * Used to synchronize {@link FeatureSelectedEvent}s with the
224     * {@link StyledFeatureLayerSelectionModel}
225     */
226 alfonx 97 @Override
227     public void performMapPaneEvent(JMapPaneEvent e) {
228 alfonx 106
229 alfonx 151 // 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 alfonx 111 /**
239 alfonx 151 * Only listen to FeatureSelectedEvents if an appropriate tool is
240 alfonx 111 * 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 mojays 109 // only listen to events directly coming from JMapPane
250     // selection (ignore selections from FilterDialog)
251 alfonx 111 if (e.getSourceObject() != this.mapPane)
252     return;
253    
254 alfonx 97 FeatureSelectedEvent fse = (FeatureSelectedEvent) e;
255    
256 alfonx 151 /**
257 alfonx 158 * Checking, that the FeatureSelectedEvent actually contains features
258     * from this layer
259 alfonx 151 */
260     final String sourceID = fse.getSourceLayer().getTitle();
261     final String syncForID = mapLayer.getTitle();
262     if (sourceID != null && syncForID != null
263 alfonx 158 && !sourceID.equals(syncForID)) {
264     LOGGER.debug("Ignoring a FeatureSelectedEvent from " + sourceID);
265 alfonx 97 return;
266 alfonx 151 }
267 alfonx 97
268 alfonx 151 LOGGER.debug("do event " + fse);
269 alfonx 111
270 alfonx 97 // Avoid event circles in propertyChange(..)
271     selectionChangeCausedByMe = true;
272    
273 alfonx 151 Collection<Feature> selectionResult = (Collection<Feature>) fse
274     .getSelectionResult();
275 alfonx 97
276 alfonx 151 // reset the selection of the DpLayerSelectionModel
277     // layerSelModel.setValueIsAdjusting(true);
278 alfonx 97
279 alfonx 151 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 alfonx 97
289 alfonx 151 for (Feature f : selectionResult) {
290     layerSelModel.addSelection(f.getID());
291     }
292 alfonx 111
293 alfonx 151 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 alfonx 111 }
300 alfonx 151 layerSelModel.setValueIsAdjusting(false);
301     }
302 alfonx 111
303     // Show selected features in the map, which is not automatically done by
304     // the origin: FeatureSelectedEvent
305 alfonx 97 changeLayerStyle(layerSelModel.getSelection());
306 alfonx 106
307 alfonx 97 // Danger of event circles in propertyChange(..) banned
308     selectionChangeCausedByMe = false;
309     }
310 alfonx 151
311 alfonx 97 }

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