/[schmitzm]/branches/2.1/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java
ViewVC logotype

Contents of /branches/2.1/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 123 - (show annotations)
Wed May 20 15:54:51 2009 UTC (15 years, 9 months ago) by alfonx
Original Path: trunk/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java
File MIME type: text/plain
File size: 11509 byte(s)
* Changed the logic to generate the Style which contains a FeatureTypeStyle for the selection. It now uses the MapLayer.getStyle() as a base (instead of styledObj.getStyle() ) and simply removes any old FeatureTypeStyle that contains Rules for an older selection. 
Why? 
1. Because the MapLayer's Style might have been changed by the AS and we don't want the Style to reset.
2. Because in the Atlas the DPLayer's getStyle() always returns the default style, ignoring any additionaly styles. 
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.Vector;
21
22 import javax.swing.JTable;
23 import javax.swing.ListSelectionModel;
24 import javax.swing.event.ListSelectionListener;
25
26 import org.geotools.feature.Feature;
27 import org.geotools.feature.FeatureCollection;
28 import org.geotools.map.MapLayer;
29 import org.geotools.styling.FeatureTypeStyle;
30 import org.geotools.styling.Style;
31 import org.opengis.filter.Filter;
32 import org.opengis.filter.FilterVisitor;
33
34 import schmitzm.geotools.gui.JMapPane;
35 import schmitzm.geotools.map.event.FeatureSelectedEvent;
36 import schmitzm.geotools.map.event.JMapPaneEvent;
37 import schmitzm.geotools.map.event.JMapPaneListener;
38 import schmitzm.geotools.styling.StylingUtil;
39 import schmitzm.lang.LangUtil;
40 import skrueger.geotools.MapPaneToolBar;
41 import skrueger.geotools.StyledMapInterface;
42
43 /**
44 * This class keeps the selection of a (feature) {@link JTable} synchronized
45 * with the {@link StyledLayerSelectionModel} of a layer. This is done by
46 * implementing:
47 * <ul>
48 * <li>a {@link PropertyChangeListener} which listens to the
49 * {@link StyledLayerSelectionModel} and accordingly changes the {@link JTable}
50 * selection</li>
51 * <li>a {@link ListSelectionListener} which listens to the {@link JTable} and
52 * accordingly changes the {@link StyledLayerSelectionModel} selection</li>
53 * </ul>
54 * After creating, the instance of this synchronizer must be added as listener
55 * to both, the {@link StyledLayerSelectionModel} and the table's
56 * {@link ListSelectionModel}.
57 *
58 * @author <a href="mailto:[email protected]">Martin Schmitz</a>
59 * (University of Bonn/Germany)
60 */
61 public class FeatureMapLayerSelectionSynchronizer extends
62 StyledLayerSelectionModelSynchronizer<StyledFeatureLayerSelectionModel>
63 implements JMapPaneListener {
64 public static final String SELECTION_STYLING = "SELECTION";
65 /**
66 * Holds the {@link MapLayer} to keep synchronized with the layer selection
67 * model.
68 */
69 protected final MapLayer mapLayer;
70 protected final StyledMapInterface<?> styledMapLayer;
71 protected final JMapPane mapPane;
72 private final MapPaneToolBar toolBar;
73
74 /**
75 * Creates a new synchronizer
76 *
77 * @param layerSelModel
78 * layer selection model to keep synchronized with the
79 * {@link MapLayer}
80 *
81 * @param mapLayer
82 * {@link MapLayer} to keep synchronized with.
83 */
84 public FeatureMapLayerSelectionSynchronizer(
85 StyledFeatureLayerSelectionModel layerSelModel,
86 StyledMapInterface<?> styledMapLayer, MapLayer mapLayer,
87 JMapPane mapPane, MapPaneToolBar toolBar) {
88
89 super(layerSelModel);
90 this.styledMapLayer = styledMapLayer;
91
92 this.mapLayer = mapLayer;
93 this.mapPane = mapPane;
94 this.toolBar = toolBar;
95 }
96
97 /**
98 * Called by {@link StyledLayerSelectionModel} when a the selection on other
99 * selection components (map, chart, ...) has changed. When calling this
100 *
101 * method changes the {@link MapLayer} selection according to the
102 * {@link StyledLayerSelectionModel} selection.
103 *
104 * @param evt
105 * an event
106 */
107 @Override
108 public void propertyChange(PropertyChangeEvent evt) {
109 if (!(evt instanceof StyledLayerSelectionEvent))
110 return;
111 StyledLayerSelectionEvent selEvt = (StyledLayerSelectionEvent) evt;
112 // Only react on own layer and ignore events invoked by
113 // this component itself
114 if (selEvt.getEmitter() != layerSelModel || selectionChangeCausedByMe)
115 return;
116 // Apply new selection on table (except this event is one of
117 // some more events)
118 Vector<String> newSelection = layerSelModel.getSelection();
119 if (newSelection == null)
120 return;
121
122 // Avoid event circles in valueChanged(..)
123 selectionChangeCausedByMe = true;
124
125 changeLayerStyle(newSelection);
126
127 // Danger of event circles in valueChanged(..) banned
128 selectionChangeCausedByMe = false;
129 }
130
131 private void changeLayerStyle(final Vector<String> newSelection) {
132 Style selectionMapStyle = null;
133 try {
134 if (newSelection.isEmpty()) {
135
136 selectionMapStyle = styledMapLayer.getStyle();
137 LOGGER.debug("NO SELECTION .. set to original style directly");
138
139 } else {
140 LOGGER.debug("SELECTION .. change style");
141
142 // We take Style from the MapLayer that is displayed at the
143 // moment. We do not use the styledMapLayer.getStyle, because in
144 // the atlas, this always return the default style, but
145 // additionaly styles might be selected.
146 // Taking the style from the mapLayer indicated, that we have to
147 // remove any selection rules first.
148 Style originalStyle = mapLayer.getStyle();
149
150 // TODO The default style is not good here. We need
151 // .createSelectionStyle(normalStyle, geoObj);
152 selectionMapStyle = StylingUtil
153 .createDefaultStyle(styledMapLayer.getGeoObject());
154
155 selectionMapStyle.getFeatureTypeStyles()[0]
156 .setName(SELECTION_STYLING);
157
158 // Symbolizer sss =
159 // selectionMapStyle.getFeatureTypeStyles()[0].getRules()[0].getSymbolizers()[0];
160 // if (sss instanceof PolygonSymbolizer) {
161 // PolygonSymbolizer ps = (PolygonSymbolizer) sss;
162 // ps.getFill().setOpacity( FilterUtil.FILTER_FAC.literal(0.5));
163 // }
164
165 // Rule selectedRule = StylingUtil.STYLE_FACTORY.createRule();
166 selectionMapStyle.getFeatureTypeStyles()[0].getRules()[0]
167 .setFilter(new Filter() {
168
169 @Override
170 public Object accept(FilterVisitor visitor,
171 Object extraData) {
172 return null;
173 }
174
175 @Override
176 public boolean evaluate(Object obj) {
177 if (obj instanceof Feature) {
178 Feature f = (Feature) obj;
179 // TODO BAD CODE! says Martin.. i am fine with it.. well.. not great...
180 for (String ffID : newSelection) {
181 if (ffID.equals(f.getID()))
182 return true;
183 }
184 return false;
185
186 }
187 return false;
188 }
189
190 });
191
192 FeatureTypeStyle[] originalFeatureTypeStyles = originalStyle.getFeatureTypeStyles();
193 FeatureTypeStyle[] newFeatureTypes ;
194 if (originalFeatureTypeStyles[originalFeatureTypeStyles.length-1].getName() != null && originalFeatureTypeStyles[originalFeatureTypeStyles.length-1].getName().equals(SELECTION_STYLING)){
195 newFeatureTypes = Arrays.copyOf(originalFeatureTypeStyles, originalFeatureTypeStyles.length-1);
196 } else {
197 newFeatureTypes = originalFeatureTypeStyles;
198 }
199 //
200 // // REMOVE any Selection_Styling FTS (usually the last one)
201 //
202 // for (FeatureTypeStyle fts : originalFeatureTypeStyles){
203 // if (fts.getName().equals(SELECTION_STYLING)) continue;
204 // newFeatureTypes =
205 //
206 // LangUtil.extendArray(
207 // originalFeatureTypeStyles, selectionMapStyle
208 // .getFeatureTypeStyles());
209 // }
210
211 // The last FTS is the selection FTS
212 newFeatureTypes = LangUtil.extendArray(newFeatureTypes, selectionMapStyle
213 .getFeatureTypeStyles());
214
215
216 selectionMapStyle.setFeatureTypeStyles(newFeatureTypes);
217
218 // selectionMapStyle.setFeatureTypeStyles(originalStyle.getF)
219
220 // Flat copy the style
221
222 // selectionMapStyle =
223 // StylingUtil.createDefaultStyle(styledMapLayer.getGeoObject());
224
225 }
226
227 mapLayer.setStyle(selectionMapStyle);
228 mapPane.refresh();
229 } catch (Exception e) {
230 LOGGER.error("Error while trying to create a selection style", e);
231 }
232 }
233
234 @Override
235 public void performMapPaneEvent(JMapPaneEvent e) {
236
237 /**
238 * Only listen to FeatureSelectionEvents if the appropriate tool is
239 * selected.
240 */
241 final int selectedTool = toolBar.getSelectedTool();
242 if (selectedTool != MapPaneToolBar.TOOL_SELECTION_ADD
243 && selectedTool != MapPaneToolBar.TOOL_SELECTION_REMOVE
244 && selectedTool != MapPaneToolBar.TOOL_SELECTION_CLEAR
245 && selectedTool != MapPaneToolBar.TOOL_SELECTION_SET) {
246 return;
247 }
248
249 if (!(e instanceof FeatureSelectedEvent)) {
250 // LOGGER.debug("Ignoring event " + e);
251 return;
252 }
253 // only listen to events directly coming from JMapPane
254 // selection (ignore selections from FilterDialog)
255 if (e.getSourceObject() != this.mapPane)
256 return;
257
258 FeatureSelectedEvent fse = (FeatureSelectedEvent) e;
259
260 // ignore event if it is caused by the DpLayerVectorSelectionModel
261 if (selectionChangeCausedByMe)
262 return;
263
264 LOGGER.debug("Do event " + fse);
265
266 // Avoid event circles in propertyChange(..)
267 selectionChangeCausedByMe = true;
268
269 if (selectedTool == MapPaneToolBar.TOOL_SELECTION_CLEAR) {
270 layerSelModel.clearSelection();
271 } else {
272 Collection<Feature> selectionResult = (Collection<Feature>) fse
273 .getSelectionResult();
274
275 // reset the selection of the DpLayerSelectionModel
276 // layerSelModel.setValueIsAdjusting(true);
277
278 if (selectedTool == MapPaneToolBar.TOOL_SELECTION_ADD) {
279 layerSelModel.setValueIsAdjusting(true);
280 for (Feature f : selectionResult) {
281 layerSelModel.addSelection(f.getID());
282 }
283 layerSelModel.setValueIsAdjusting(false);
284 } else if (selectedTool == MapPaneToolBar.TOOL_SELECTION_SET) {
285 layerSelModel.setValueIsAdjusting(true);
286 layerSelModel.clearSelection();
287
288 for (Feature f : selectionResult) {
289 layerSelModel.addSelection(f.getID());
290 }
291
292 LOGGER.debug("Setting selection to " + selectionResult.size());
293 layerSelModel.setValueIsAdjusting(false);
294 } else if (selectedTool == MapPaneToolBar.TOOL_SELECTION_REMOVE) {
295 layerSelModel.setValueIsAdjusting(true);
296 for (Feature f : selectionResult) {
297 layerSelModel.removeSelection(f.getID());
298 }
299 layerSelModel.setValueIsAdjusting(false);
300 }
301 } // els it's not a Clear Selection command
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 }

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