/[schmitzm]/branches/1.0-gt2-2.6/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java
ViewVC logotype

Contents of /branches/1.0-gt2-2.6/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 415 - (show annotations)
Thu Sep 24 17:58:32 2009 UTC (15 years, 5 months ago) by alfonx
File MIME type: text/plain
File size: 12875 byte(s)
* GP-Feature: In the MapComposer it is now BASICALLY possible to change the CRS and format of the Grid/Ruler on the left/bottom. At the moment only two formatters are available, one for DHDN in Germany, and one for lat/lon. 
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. Krüger - additional utility classes
29 ******************************************************************************/
30 /**
31 Copyright 2008 Stefan Alfons Krüger
32
33 atlas-framework - This file is part of the Atlas Framework
34
35 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.
36 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.
37 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
38
39 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.
40 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.
41 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.
42 **/
43 package skrueger.geotools.selection;
44
45 import java.beans.PropertyChangeEvent;
46 import java.beans.PropertyChangeListener;
47 import java.util.HashSet;
48 import java.util.Iterator;
49 import java.util.Set;
50 import java.util.Vector;
51
52 import javax.swing.JTable;
53 import javax.swing.ListSelectionModel;
54 import javax.swing.event.ListSelectionListener;
55
56 import org.geotools.map.MapLayer;
57 import org.geotools.styling.FeatureTypeStyle;
58 import org.geotools.styling.Style;
59 import org.opengis.feature.simple.SimpleFeature;
60 import org.opengis.filter.identity.FeatureId;
61
62 import schmitzm.geotools.FilterUtil;
63 import schmitzm.geotools.gui.JMapPane;
64 import schmitzm.geotools.map.event.FeatureSelectedEvent;
65 import schmitzm.geotools.map.event.JMapPaneEvent;
66 import schmitzm.geotools.map.event.JMapPaneListener;
67 import schmitzm.geotools.styling.StylingUtil;
68 import skrueger.geotools.MapPaneToolBar;
69 import skrueger.geotools.StyledLayerInterface;
70
71 /**
72 * This class keeps the selection of a (feature) {@link JTable} synchronized
73 * with the {@link StyledLayerSelectionModel} of a layer. This is done by
74 * implementing:
75 * <ul>
76 * <li>a {@link PropertyChangeListener} which listens to the
77 * {@link StyledLayerSelectionModel} and accordingly changes the {@link JTable}
78 * selection</li>
79 * <li>a {@link ListSelectionListener} which listens to the {@link JTable} and
80 * accordingly changes the {@link StyledLayerSelectionModel} selection</li>
81 * </ul>
82 * After creating, the instance of this synchronizer must be added as listener
83 * to both, the {@link StyledLayerSelectionModel} and the table's
84 * {@link ListSelectionModel}.
85 *
86 * @author <a href="mailto:[email protected]">Martin Schmitz</a>
87 * (University of Bonn/Germany)
88 */
89 public class FeatureMapLayerSelectionSynchronizer extends
90 StyledLayerSelectionModelSynchronizer<StyledFeatureLayerSelectionModel>
91 implements JMapPaneListener {
92 public static final String SELECTION_STYLING = "SELECTION";
93 /**
94 * Holds the {@link MapLayer} to keep synchronized with the layer selection
95 * model.
96 */
97 protected final MapLayer mapLayer;
98 protected final StyledLayerInterface<?> styledLayer;
99 protected final JMapPane mapPane;
100 private final MapPaneToolBar toolBar;
101
102 /**
103 * Creates a new synchronizer
104 *
105 * @param layerSelModel
106 * layer selection model to keep synchronized with the
107 * {@link MapLayer}
108 *
109 * @param mapLayer
110 * {@link MapLayer} to keep synchronized with.
111 */
112 public FeatureMapLayerSelectionSynchronizer(
113 StyledFeatureLayerSelectionModel layerSelModel,
114 StyledLayerInterface<?> styledLayer, MapLayer mapLayer,
115 JMapPane mapPane, MapPaneToolBar toolBar) {
116
117 super(layerSelModel);
118 this.styledLayer = styledLayer;
119
120 this.mapLayer = mapLayer;
121 this.mapPane = mapPane;
122 this.toolBar = toolBar;
123 }
124
125 /**
126 * Called by {@link StyledLayerSelectionModel} when a the selection on other
127 * selection components (map, chart, ...) has changed. When calling this
128 *
129 * method changes the {@link MapLayer} selection according to the
130 * {@link StyledLayerSelectionModel} selection.
131 *
132 * @param evt
133 * an event
134 */
135 @Override
136 public void propertyChange(PropertyChangeEvent evt) {
137
138 if (!isEnabled())
139 return;
140
141 if (!(evt instanceof StyledLayerSelectionEvent))
142 return;
143 StyledLayerSelectionEvent selEvt = (StyledLayerSelectionEvent) evt;
144 // Only react on own layer and ignore events invoked by
145 // this component itself
146 if (selEvt.getEmitter() != layerSelModel || selectionChangeCausedByMe)
147 return;
148 // Apply new selection on table (except this event is one of
149 // some more events)
150 Vector<String> newSelection = layerSelModel.getSelection();
151 if (newSelection == null)
152 return;
153
154 // Avoid event circles in valueChanged(..)
155 selectionChangeCausedByMe = true;
156
157 changeLayerStyle(newSelection);
158
159 // Danger of event circles in valueChanged(..) banned
160 selectionChangeCausedByMe = false;
161 }
162
163 /**
164 * Changes the Style of the {@link MapLayer} to reflect changes of the
165 * selection.
166 *
167 * @param newSelection
168 * A {@link Vector} of SimpleFeature-IDs that are selected.
169 */
170 private void changeLayerStyle(final Vector<String> newSelection) {
171 try {
172 // GTRenderer r = mapPane.getRenderer();
173 // if (r instanceof ShapefileRenderer) {
174 // ShapefileRenderer sfr = (ShapefileRenderer)r;
175 // sfr.setCaching(false);
176 // }
177 //
178
179 Style originalStyle = mapLayer.getStyle();
180 if (newSelection.isEmpty()) {
181
182 // Check if the Style contains a SELECTION FTS
183
184 FeatureTypeStyle[] clone = originalStyle.featureTypeStyles().toArray( new FeatureTypeStyle[] {} ).clone();
185
186 for (FeatureTypeStyle fts : clone) {
187 if (fts.getName() != null
188 && fts.getName().equals(SELECTION_STYLING)) {
189 originalStyle.featureTypeStyles().remove(fts);
190
191 mapPane.refresh();
192
193 return;
194 }
195 }
196
197 } else {
198 LOGGER.debug("SELECTION .. change style");
199
200 // We take Style from the MapLayer that is displayed at the
201 // moment. We do not use the styledLayer.getStyle, because in
202 // the atlas, this always return the default style, but
203 // additional styles might be selected.
204 // Taking the style from the mapLayer indicated, that we have to
205 // remove any selection rules first.
206
207 FeatureTypeStyle selectionFTStyle = StylingUtil
208 .createSelectionStyle(styledLayer.getGeoObject());
209
210 selectionFTStyle.setName(SELECTION_STYLING);
211
212 /**
213 *
214 * Add a Filter to the selectionMapStyle, so that it is only
215 * used on objects that are selected. <br/>
216 *
217 * Note 1:<br/>
218 * It is NEVER allowed to GeoTools extend Filter () { .. } (and
219 * write tests into the evaluate block). Especially for the
220 * ShapeFileRenderer, we may only use a geotools Filter.<br/>
221 *
222 * Note 2:<br/>
223 * The FilterUtil.FILTER_FAC2.id(fids) wants a set of
224 * FeatureId-Objects!
225 */
226
227 Set<FeatureId> fids = new HashSet<FeatureId>();
228 for (String fid : newSelection) {
229 fids.add(FilterUtil.FILTER_FAC2.featureId(fid));
230 }
231
232 selectionFTStyle.rules().get(0).setFilter(
233 FilterUtil.FILTER_FAC2.id(fids));
234
235 // Maybe there has already been another selection
236 // FeatureTypeStyle... Let's replace it...
237 boolean foundAndReplaced = false;
238 for (FeatureTypeStyle fts : originalStyle.featureTypeStyles()) {
239 if (fts.getName() != null
240 && fts.getName().equals(SELECTION_STYLING)) {
241 foundAndReplaced = true;
242 fts.rules().clear();
243 fts.rules().addAll(selectionFTStyle.rules());
244 break;
245 }
246 }
247 if (!foundAndReplaced) {
248 originalStyle.featureTypeStyles().add(selectionFTStyle);
249 }
250
251 // Refresh the map
252 mapPane.refresh();
253 }
254 //
255 // if (r instanceof ShapefileRenderer) {
256 // ShapefileRenderer sfr = (ShapefileRenderer)r;
257 // sfr.setCaching(true);
258 // }
259
260
261 } catch (Exception e) {
262 LOGGER.error("Error while trying to create a selection style", e);
263 }
264 }
265
266 /**
267 * Used to synchronize {@link FeatureSelectedEvent}s with the
268 * {@link StyledFeatureLayerSelectionModel}
269 */
270 @Override
271 public void performMapPaneEvent(JMapPaneEvent e) {
272
273 // Ignore event if it is caused by us or the synchronizer is disabled.
274 if (!isEnabled() || selectionChangeCausedByMe)
275 return;
276
277 if (!(e instanceof FeatureSelectedEvent)) {
278 // LOGGER.debug("Ignoring event " + e);
279 return;
280 }
281
282 /**
283 * Only listen to FeatureSelectedEvents if an appropriate tool is
284 * selected.
285 */
286 final int selectedTool = toolBar.getSelectedTool();
287 if (selectedTool != MapPaneToolBar.TOOL_SELECTION_ADD
288 && selectedTool != MapPaneToolBar.TOOL_SELECTION_REMOVE
289 && selectedTool != MapPaneToolBar.TOOL_SELECTION_SET) {
290 return;
291 }
292
293 // only listen to events directly coming from JMapPane
294 // selection (ignore selections from FilterDialog)
295 if (e.getSourceObject() != this.mapPane)
296 return;
297
298 FeatureSelectedEvent fse = (FeatureSelectedEvent) e;
299
300 /**
301 * Checking, that the FeatureSelectedEvent actually contains features
302 * from this layer
303 */
304 final String sourceID = fse.getSourceLayer().getTitle();
305 final String syncForID = mapLayer.getTitle();
306 if (sourceID != null && syncForID != null
307 && !sourceID.equals(syncForID)) {
308 LOGGER.debug("Ignoring a FeatureSelectedEvent from " + sourceID);
309 return;
310 }
311
312 LOGGER.debug("do event " + fse);
313
314 // Avoid event circles in propertyChange(..)
315 selectionChangeCausedByMe = true;
316
317 Iterator<SimpleFeature> fi = fse.getSelectionResult().iterator();
318
319 // reset the selection of the DpLayerSelectionModel
320 // layerSelModel.setValueIsAdjusting(true);
321
322 if (selectedTool == MapPaneToolBar.TOOL_SELECTION_ADD) {
323 layerSelModel.setValueIsAdjusting(true);
324
325 for (int fIdx = 0; fi.hasNext(); fIdx++) {
326 SimpleFeature f = fi.next();
327 layerSelModel.addSelection(f.getID());
328 }
329 layerSelModel.setValueIsAdjusting(false);
330 } else if (selectedTool == MapPaneToolBar.TOOL_SELECTION_SET) {
331 layerSelModel.setValueIsAdjusting(true);
332 layerSelModel.clearSelection();
333
334 for (int fIdx = 0; fi.hasNext(); fIdx++) {
335 SimpleFeature f = fi.next();
336 layerSelModel.addSelection(f.getID());
337 }
338
339 // LOGGER.debug("Setting selection to " + fi.());
340
341 layerSelModel.setValueIsAdjusting(false);
342 } else if (selectedTool == MapPaneToolBar.TOOL_SELECTION_REMOVE) {
343 layerSelModel.setValueIsAdjusting(true);
344 for (int fIdx = 0; fi.hasNext(); fIdx++) {
345 SimpleFeature f = fi.next();
346 layerSelModel.removeSelection(f.getID());
347 }
348 layerSelModel.setValueIsAdjusting(false);
349 }
350
351 // Show selected features in the map, which is not automatically done by
352 // the origin: FeatureSelectedEvent
353 changeLayerStyle(layerSelModel.getSelection());
354
355 // Danger of event circles in propertyChange(..) banned
356 selectionChangeCausedByMe = false;
357 }
358
359 }

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