001: /*
002: * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI for
003: * 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 modify it under
008: * the terms of the GNU General Public License as published by the Free Software
009: * Foundation; either version 2 of the License, or (at your option) any later
010: * version.
011: *
012: * This program is distributed in the hope that it will be useful, but WITHOUT
013: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
014: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
015: * details.
016: *
017: * You should have received a copy of the GNU General Public License along with
018: * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
019: * 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: package com.vividsolutions.jump.workbench.ui.renderer;
033:
034: import java.awt.Graphics2D;
035: import java.util.ArrayList;
036: import java.util.Collection;
037: import java.util.Collections;
038: import java.util.Map;
039:
040: import com.vividsolutions.jts.geom.Envelope;
041: import com.vividsolutions.jts.util.Assert;
042: import com.vividsolutions.jump.workbench.model.Layer;
043: import com.vividsolutions.jump.workbench.model.Layerable;
044: import com.vividsolutions.jump.workbench.ui.LayerViewPanel;
045:
046: //[sstein] : 14.08.2005 added variable maxFeatures with getters and setters
047:
048: public class LayerRenderer extends FeatureCollectionRenderer {
049: private Layer layer;
050:
051: private LayerViewPanel panel;
052:
053: public static final String ALWAYS_USE_IMAGE_CACHING_KEY = LayerRenderer.class
054: .getName()
055: + " - ALWAYS USE IMAGE CACHING";
056:
057: public LayerRenderer(final Layer layer, LayerViewPanel panel) {
058: //Use layer as the contentID [Jon Aquino]
059: super (layer, panel, new ImageCachingFeatureCollectionRenderer(
060: layer, panel) {
061: protected ThreadSafeImage getImage() {
062: if (!layer.isVisible()) {
063: return null;
064: }
065:
066: return super .getImage();
067: }
068:
069: public Runnable createRunnable() {
070: if (!layer.isVisible()) {
071: //If the cached image is null, leave it alone. [Jon
072: // Aquino]
073: return null;
074: }
075:
076: return super .createRunnable();
077: }
078: });
079: this .layer = layer;
080: this .panel = panel;
081: }
082:
083: public Runnable createRunnable() {
084: if (!render(layer, panel)) {
085: return null;
086: }
087: return super .createRunnable();
088: }
089:
090: public void copyTo(Graphics2D graphics) {
091: if (!render(layer, panel)) {
092: return;
093: }
094: super .copyTo(graphics);
095: }
096:
097: public static boolean render(Layerable layerable,
098: LayerViewPanel panel) {
099: if (!layerable.isVisible()) {
100: return false;
101: }
102: if (!layerable.getLayerManager().getLayerables(Layerable.class)
103: .contains(layerable)) {
104: // Get here after deleting a layer. [Jon Aquino 2005-03-29]
105: return false;
106: }
107: return withinVisibleScaleRange(layerable, panel);
108: }
109:
110: public static boolean withinVisibleScaleRange(Layerable layerable,
111: LayerViewPanel panel) {
112: // When working with scale, the max is less than the min.
113: // [Jon Aquino 2005-03-01]
114: Assert.isTrue(layerable.getMaxScale() == null
115: || layerable.getMinScale() == null
116: || layerable.getMaxScale().doubleValue() <= layerable
117: .getMinScale().doubleValue());
118: if (!layerable.isScaleDependentRenderingEnabled()) {
119: return true;
120: }
121: if (layerable.getMaxScale() != null
122: && scale(panel) < layerable.getMaxScale().doubleValue()) {
123: return false;
124: }
125: if (layerable.getMinScale() != null
126: && scale(panel) > layerable.getMinScale().doubleValue()) {
127: return false;
128: }
129: return true;
130: }
131:
132: /**
133: * @return the inverse of the viewport's scale; it is inverted so that it
134: * increases as the user zooms out, as is usually expected
135: */
136: private static double scale(LayerViewPanel panel) {
137: return 1d / panel.getViewport().getScale();
138: }
139:
140: protected Collection styles() {
141: //new ArrayList to avoid ConcurrentModificationExceptions. [Jon Aquino]
142: ArrayList styles = new ArrayList(layer.getStyles());
143: styles.remove(layer.getVertexStyle());
144: styles.remove(layer.getLabelStyle());
145:
146: //Move to last. [Jon Aquino]
147: styles.add(layer.getVertexStyle());
148: styles.add(layer.getLabelStyle());
149:
150: return styles;
151: }
152:
153: protected boolean useImageCaching(Map layerToFeaturesMap) {
154: if (layer.getBlackboard().get(ALWAYS_USE_IMAGE_CACHING_KEY,
155: false)) {
156: return true;
157: }
158: return super .useImageCaching(layerToFeaturesMap);
159: }
160:
161: protected Map layerToFeaturesMap() {
162: Envelope viewportEnvelope = panel.getViewport()
163: .getEnvelopeInModelCoordinates();
164:
165: return Collections.singletonMap(layer, layer
166: .getFeatureCollectionWrapper().query(viewportEnvelope));
167: }
168:
169: /**
170: * @return Returns the number of maxFeatures to render
171: * as vector graphic.
172: */
173: public int getMaxFeatures() {
174: return super .getMaxFeatures();
175: }
176:
177: /**
178: * @param maxFeatures The maximum number of Features to render
179: * as vector graphic.<p>
180: * Use this method before using method render(Object contentID) or render(Object contentID, boolean clearImageCache)
181: */
182: public void setMaxFeatures(int maxFeatures) {
183: super.setMaxFeatures(maxFeatures);
184: }
185:
186: }
|