package com.revolsys.swing.map.layer.record.renderer; import java.util.List; import java.util.Map; import javax.swing.Icon; import com.revolsys.geometry.model.BoundingBox; import com.revolsys.geometry.model.TopologyException; import com.revolsys.logging.Logs; import com.revolsys.swing.Icons; import com.revolsys.swing.map.Viewport2D; import com.revolsys.swing.map.layer.AbstractLayer; import com.revolsys.swing.map.layer.LayerRenderer; import com.revolsys.swing.map.layer.record.AbstractRecordLayer; import com.revolsys.swing.map.layer.record.LayerRecord; import com.revolsys.util.Cancellable; /** * Use the first renderer which is visible at the current scale, ignore all * others. Changes when the scale changes. */ public class ScaleMultipleRenderer extends AbstractMultipleRenderer { private static final Icon ICON = Icons.getIcon("style_scale"); private transient long lastScale = 0; private transient AbstractRecordLayerRenderer renderer; public ScaleMultipleRenderer(final AbstractRecordLayer layer, final LayerRenderer<?> parent) { super("scaleStyle", layer, parent); setIcon(ICON); } public ScaleMultipleRenderer(final Map<String, ? extends Object> properties) { super("scaleStyle", "Scale Styles"); setIcon(ICON); setProperties(properties); } @Override public ScaleMultipleRenderer clone() { final ScaleMultipleRenderer clone = (ScaleMultipleRenderer)super.clone(); clone.lastScale = 0; clone.renderer = null; return clone; } private AbstractRecordLayerRenderer getRenderer(final Viewport2D viewport) { final long scaleForVisible = (long)viewport.getScaleForVisible(); if (scaleForVisible == this.lastScale && this.renderer != null) { if (this.renderer.isVisible(scaleForVisible)) { return this.renderer; } else { return null; } } else { this.lastScale = scaleForVisible; for (final AbstractRecordLayerRenderer renderer : getRenderers()) { if (renderer.isVisible(scaleForVisible)) { this.renderer = renderer; return renderer; } } return null; } } @Override public boolean isVisible(final LayerRecord object) { if (super.isVisible() && super.isVisible(object)) { if (this.renderer != null) { return this.renderer.isVisible(object); } } return false; } @Override public void render(final Viewport2D viewport, final Cancellable cancellable, final AbstractRecordLayer layer) { if (layer.hasGeometryField()) { final AbstractRecordLayerRenderer renderer = getRenderer(viewport); if (renderer != null) { renderer.render(viewport, cancellable, layer); } } } // NOTE: Needed for filter styles @Override public void renderRecord(final Viewport2D viewport, final BoundingBox visibleArea, final AbstractLayer layer, final LayerRecord record) { final AbstractRecordLayerRenderer renderer = getRenderer(viewport); if (renderer != null) { if (isVisible(record)) { try { renderer.renderRecord(viewport, visibleArea, layer, record); } catch (final TopologyException e) { } catch (final Throwable e) { Logs.error(this, "Unabled to render " + layer.getName() + " #" + record.getIdentifier(), e); } } } } @Override // NOTE: Needed for multiple styles protected void renderRecords(final Viewport2D viewport, final Cancellable cancellable, final AbstractRecordLayer layer, final List<LayerRecord> records) { final BoundingBox visibleArea = viewport.getBoundingBox(); final AbstractRecordLayerRenderer renderer = getRenderer(viewport); if (renderer != null) { for (final LayerRecord record : cancellable.cancellable(records)) { if (isVisible(record)) { try { renderer.renderRecord(viewport, visibleArea, layer, record); } catch (final TopologyException e) { } } } } } @Override public void renderSelectedRecord(final Viewport2D viewport, final AbstractLayer layer, final LayerRecord object) { final AbstractRecordLayerRenderer renderer = getRenderer(viewport); if (renderer != null) { if (isVisible(object)) { try { renderer.renderSelectedRecord(viewport, layer, object); } catch (final Throwable e) { Logs.error(this, "Unabled to render " + layer.getName() + " #" + object.getIdentifier(), e); } } } } }