001: /*
002: * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
003: * for visualizing and manipulating spatial features with geometry and attributes.
004: *
005: * Copyright (C) 2003 Vivid Solutions
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: *
021: * For more information, contact:
022: *
023: * Vivid Solutions
024: * Suite #1A
025: * 2328 Government Street
026: * Victoria BC V8T 5G5
027: * Canada
028: *
029: * (250)385-6040
030: * www.vividsolutions.com
031: */
032:
033: package com.vividsolutions.jump.workbench.ui;
034:
035: import java.util.ArrayList;
036: import java.util.Collection;
037: import java.util.HashMap;
038: import java.util.HashSet;
039: import java.util.Iterator;
040: import java.util.List;
041: import java.util.Map;
042:
043: import com.vividsolutions.jts.geom.Geometry;
044: import com.vividsolutions.jump.feature.Feature;
045: import com.vividsolutions.jump.util.CollectionMap;
046: import com.vividsolutions.jump.workbench.model.Layer;
047:
048: /**
049: * Superclass for holding a user-selected collection of {@link
050: * Feature} items.
051: */
052:
053: public abstract class AbstractSelection {
054: private Map layerMap = new HashMap();
055:
056: public abstract String getRendererContentID();
057:
058: private AbstractSelection child;
059:
060: private AbstractSelection parent;
061:
062: private SelectionManager selectionManager;
063:
064: public AbstractSelection(SelectionManager selectionManager) {
065: this .selectionManager = selectionManager;
066: }
067:
068: public abstract List items(Geometry geometry);
069:
070: public Collection items(Geometry geometry, Collection indices) {
071: List allItems = items(geometry);
072: ArrayList items = new ArrayList();
073: for (Iterator i = indices.iterator(); i.hasNext();) {
074: Integer index = (Integer) i.next();
075: items.add(allItems.get(index.intValue()));
076: }
077: return items;
078: }
079:
080: /**
081: * Note that some features in the map may not have selected items.
082: */
083: public CollectionMap getFeatureToSelectedItemIndexCollectionMap(
084: Layer layer) {
085: if (!layerMap.containsKey(layer)) {
086: layerMap.put(layer, new CollectionMap(HashMap.class,
087: HashSet.class));
088: }
089: return (CollectionMap) layerMap.get(layer);
090: }
091:
092: public Collection getSelectedItemIndices(Layer layer,
093: Feature feature) {
094: Collection indices = getFeatureToSelectedItemIndexCollectionMap(
095: layer).getItems(feature);
096: return indices == null ? new ArrayList() : indices;
097: }
098:
099: /**
100: * Note that some features in the map may not have selected items.
101: */
102: public CollectionMap getFeatureToSelectedItemCollectionMap(
103: Layer layer) {
104: CollectionMap collectionMap = new CollectionMap();
105: for (Iterator i = getFeatureToSelectedItemIndexCollectionMap(
106: layer).keySet().iterator(); i.hasNext();) {
107: Feature feature = (Feature) i.next();
108: collectionMap.put(feature, items(feature.getGeometry(),
109: getFeatureToSelectedItemIndexCollectionMap(layer)
110: .getItems(feature)));
111: }
112: return collectionMap;
113: }
114:
115: public Collection getLayersWithSelectedItems() {
116: ArrayList layersWithSelectedItems = new ArrayList();
117: for (Iterator i = layerMap.keySet().iterator(); i.hasNext();) {
118: Layer layer = (Layer) i.next();
119: if (!getFeaturesWithSelectedItems(layer).isEmpty()) {
120: layersWithSelectedItems.add(layer);
121: }
122: }
123: return layersWithSelectedItems;
124: }
125:
126: public Collection getFeaturesWithSelectedItems() {
127: ArrayList featuresWithSelectedItems = new ArrayList();
128: for (Iterator i = layerMap.keySet().iterator(); i.hasNext();) {
129: Layer layer = (Layer) i.next();
130: featuresWithSelectedItems
131: .addAll(getFeaturesWithSelectedItems(layer));
132: }
133: return featuresWithSelectedItems;
134: }
135:
136: public Collection getFeaturesWithSelectedItems(Layer layer) {
137: ArrayList featuresWithSelectedItems = new ArrayList();
138: for (Iterator i = getFeatureToSelectedItemIndexCollectionMap(
139: layer).keySet().iterator(); i.hasNext();) {
140: Feature feature = (Feature) i.next();
141: if (!getFeatureToSelectedItemIndexCollectionMap(layer)
142: .getItems(feature).isEmpty()) {
143: featuresWithSelectedItems.add(feature);
144: }
145: }
146: return featuresWithSelectedItems;
147: }
148:
149: public Collection getSelectedItems() {
150: ArrayList selectedItems = new ArrayList();
151: for (Iterator i = new ArrayList(layerMap.keySet()).iterator(); i
152: .hasNext();) {
153: Layer layer = (Layer) i.next();
154: selectedItems.addAll(getSelectedItems(layer));
155: }
156: return selectedItems;
157: }
158:
159: public Collection getSelectedItems(Layer layer) {
160: ArrayList selectedItems = new ArrayList();
161: for (Iterator i = getFeatureToSelectedItemIndexCollectionMap(
162: layer).keySet().iterator(); i.hasNext();) {
163: Feature feature = (Feature) i.next();
164: selectedItems.addAll(getSelectedItems(layer, feature));
165: }
166: return selectedItems;
167: }
168:
169: public Collection getSelectedItems(Layer layer, Feature feature) {
170: return getSelectedItems(layer, feature, feature.getGeometry());
171: }
172:
173: /**
174: * @param geometry the feature's Geometry or equivalent; that is, a clone or
175: * similar enough Geometry from which Geometries can be retrieved using
176: * the selection indices.
177: */
178: public Collection getSelectedItems(Layer layer, Feature feature,
179: Geometry geometry) {
180: return items(geometry,
181: getFeatureToSelectedItemIndexCollectionMap(layer)
182: .getItems(feature));
183: }
184:
185: public Collection indices(Geometry geometry, Collection items) {
186: List allItems = items(geometry);
187: ArrayList indices = new ArrayList();
188: for (Iterator i = items.iterator(); i.hasNext();) {
189: Object item = i.next();
190: indices.add(new Integer(allItems.indexOf(item)));
191: }
192: return indices;
193: }
194:
195: public void unselectItems(Layer layer,
196: CollectionMap featureToItemCollectionMap) {
197: boolean originalPanelUpdatesEnabled = selectionManager
198: .arePanelUpdatesEnabled();
199: selectionManager.setPanelUpdatesEnabled(false);
200: try {
201: for (Iterator i = featureToItemCollectionMap.keySet()
202: .iterator(); i.hasNext();) {
203: Feature feature = (Feature) i.next();
204: unselectItems(layer, feature,
205: featureToItemCollectionMap.getItems(feature));
206: }
207: } finally {
208: selectionManager
209: .setPanelUpdatesEnabled(originalPanelUpdatesEnabled);
210: }
211: updatePanel();
212: }
213:
214: public void selectItems(Layer layer,
215: CollectionMap featureToItemCollectionMap) {
216: boolean originalPanelUpdatesEnabled = selectionManager
217: .arePanelUpdatesEnabled();
218: selectionManager.setPanelUpdatesEnabled(false);
219: try {
220: for (Iterator i = featureToItemCollectionMap.keySet()
221: .iterator(); i.hasNext();) {
222: Feature feature = (Feature) i.next();
223: selectItems(layer, feature, featureToItemCollectionMap
224: .getItems(feature));
225: }
226: } finally {
227: selectionManager
228: .setPanelUpdatesEnabled(originalPanelUpdatesEnabled);
229: }
230: updatePanel();
231: }
232:
233: public void selectItems(Layer layer, Feature feature,
234: Collection items) {
235: Collection itemsToSelect = itemsNotSelectedInAncestors(layer,
236: feature, items);
237: boolean originalPanelUpdatesEnabled = selectionManager
238: .arePanelUpdatesEnabled();
239: selectionManager.setPanelUpdatesEnabled(false);
240: try {
241: unselectInDescendants(layer, feature, itemsToSelect);
242: getFeatureToSelectedItemIndexCollectionMap(layer).addItems(
243: feature,
244: indices(feature.getGeometry(), itemsToSelect));
245: } finally {
246: selectionManager
247: .setPanelUpdatesEnabled(originalPanelUpdatesEnabled);
248: }
249: updatePanel();
250: }
251:
252: public void unselectItems(Layer layer, Feature feature,
253: Collection items) {
254: boolean originalPanelUpdatesEnabled = selectionManager
255: .arePanelUpdatesEnabled();
256: selectionManager.setPanelUpdatesEnabled(false);
257: try {
258: getFeatureToSelectedItemIndexCollectionMap(layer)
259: .removeItems(feature,
260: indices(feature.getGeometry(), items));
261: } finally {
262: selectionManager
263: .setPanelUpdatesEnabled(originalPanelUpdatesEnabled);
264: }
265: updatePanel();
266: }
267:
268: public Collection itemsNotSelectedInAncestors(Layer layer,
269: Feature feature, Collection items) {
270: ArrayList itemsNotSelectedInAncestors = new ArrayList();
271:
272: if (layer.isSelectable()) {
273: for (Iterator i = items.iterator(); i.hasNext();) {
274: Geometry item = (Geometry) i.next();
275: if (!selectedInAncestors(layer, feature, item)) {
276: itemsNotSelectedInAncestors.add(item);
277: }
278: }
279: }
280:
281: return itemsNotSelectedInAncestors;
282: }
283:
284: protected abstract boolean selectedInAncestors(Layer layer,
285: Feature feature, Geometry item);
286:
287: protected abstract void unselectInDescendants(Layer layer,
288: Feature feature, Collection items);
289:
290: public void selectItems(Layer layer, Feature feature) {
291: selectItems(layer, feature, items(feature.getGeometry()));
292: }
293:
294: public void selectItems(Layer layer, Collection features) {
295: boolean originalPanelUpdatesEnabled = selectionManager
296: .arePanelUpdatesEnabled();
297: selectionManager.setPanelUpdatesEnabled(false);
298: try {
299: for (Iterator i = new ArrayList(features).iterator(); i
300: .hasNext();) {
301: Feature feature = (Feature) i.next();
302: selectItems(layer, feature);
303: }
304: } finally {
305: selectionManager
306: .setPanelUpdatesEnabled(originalPanelUpdatesEnabled);
307: }
308: updatePanel();
309: }
310:
311: public void unselectFromFeaturesWithModifiedItemCounts(Layer layer,
312: Collection features, Collection oldFeatureClones) {
313: ArrayList featuresToUnselect = new ArrayList();
314: Iterator j = oldFeatureClones.iterator();
315: j.hasNext();
316: for (Iterator i = features.iterator(); i.hasNext();) {
317: Feature feature = (Feature) i.next();
318: Feature oldFeatureClone = (Feature) j.next();
319: if (items(feature.getGeometry()).size() != items(
320: oldFeatureClone.getGeometry()).size()) {
321: featuresToUnselect.add(feature);
322: }
323: }
324: unselectItems(layer, featuresToUnselect);
325: }
326:
327: public void unselectItems() {
328: layerMap.clear();
329: updatePanel();
330: }
331:
332: public void unselectItems(Layer layer) {
333: layerMap.remove(layer);
334: updatePanel();
335: }
336:
337: public void unselectItems(Layer layer, Collection features) {
338: boolean originalPanelUpdatesEnabled = selectionManager
339: .arePanelUpdatesEnabled();
340: selectionManager.setPanelUpdatesEnabled(false);
341: try {
342: for (Iterator i = features.iterator(); i.hasNext();) {
343: Feature feature = (Feature) i.next();
344: unselectItems(layer, feature);
345: }
346: } finally {
347: selectionManager
348: .setPanelUpdatesEnabled(originalPanelUpdatesEnabled);
349: }
350: updatePanel();
351: }
352:
353: public void unselectItems(Layer layer, Feature feature) {
354: getFeatureToSelectedItemIndexCollectionMap(layer).remove(
355: feature);
356: updatePanel();
357: }
358:
359: public void unselectItem(Layer layer, Feature feature,
360: int selectedItemIndex) {
361: getFeatureToSelectedItemIndexCollectionMap(layer).removeItem(
362: feature, new Integer(selectedItemIndex));
363: }
364:
365: private void updatePanel() {
366: selectionManager.updatePanel();
367: }
368:
369: public void setChild(AbstractSelection child) {
370: this .child = child;
371: }
372:
373: public void setParent(AbstractSelection parent) {
374: this .parent = parent;
375: }
376:
377: protected AbstractSelection getChild() {
378: return child;
379: }
380:
381: protected AbstractSelection getParent() {
382: return parent;
383: }
384:
385: }
|