/* Copyright (C) 2001, 2006 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All Rights Reserved. */ package gov.nasa.worldwind.layers; import gov.nasa.worldwind.WWObjectImpl; import gov.nasa.worldwind.avlist.AVKey; import gov.nasa.worldwind.geom.Position; import gov.nasa.worldwind.render.DrawContext; import gov.nasa.worldwind.util.Logging; /** * @author tag * @version $Id: AbstractLayer.java 4442 2008-02-12 09:57:40Z tgaskins $ */ public abstract class AbstractLayer extends WWObjectImpl implements Layer { private boolean enabled = true; private boolean pickable = true; private double opacity = 1d; private double minActiveAltitude = -Double.MAX_VALUE; private double maxActiveAltitude = Double.MAX_VALUE; public boolean isEnabled() { return this.enabled; } public boolean isPickEnabled() { return pickable; } public void setPickEnabled(boolean pickable) { this.pickable = pickable; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public String getName() { Object n = this.getValue(AVKey.DISPLAY_NAME); return n != null ? n.toString() : this.toString(); } public void setName(String name) { this.setValue(AVKey.DISPLAY_NAME, name); } public String toString() { Object n = this.getValue(AVKey.DISPLAY_NAME); return n != null ? n.toString() : super.toString(); } public double getOpacity() { return opacity; } public void setOpacity(double opacity) { this.opacity = opacity; } public double getMinActiveAltitude() { return minActiveAltitude; } public void setMinActiveAltitude(double minActiveAltitude) { this.minActiveAltitude = minActiveAltitude; } public double getMaxActiveAltitude() { return maxActiveAltitude; } public void setMaxActiveAltitude(double maxActiveAltitude) { this.maxActiveAltitude = maxActiveAltitude; } public double getScale() { Object o = this.getValue(AVKey.MAP_SCALE); return o != null && o instanceof Double ? (Double) o : 1; } /** * Indicates whether the layer is in the view. The method implemented here is a default indicating the layer is in * view. Subclasses able to determine their presence in the view should override this implementation. * * @param dc the current draw context * @return <code>true</code> if the layer is in the view, <code>false</code> otherwise. */ public boolean isLayerInView(DrawContext dc) { if (dc == null) { String message = Logging.getMessage("nullValue.DrawContextIsNull"); Logging.logger().severe(message); throw new IllegalStateException(message); } return true; } /** * Indicates whether the layer is active based on arbitrary criteria. The method implemented here is a default * indicating the layer is active if the current altitude is within the layer's min and max active altitudes. * Subclasses able to consider more criteria should override this implementation. * * @param dc the current draw context * @return <code>true</code> if the layer is active, <code>false</code> otherwise. */ public boolean isLayerActive(DrawContext dc) { if (dc == null) { String message = Logging.getMessage("nullValue.DrawContextIsNull"); Logging.logger().severe(message); throw new IllegalStateException(message); } if (null == dc.getView()) { String message = Logging.getMessage("layers.AbstractLayer.NoViewSpecifiedInDrawingContext"); Logging.logger().severe(message); throw new IllegalStateException(message); } Position eyePos = dc.getView().getEyePosition(); if (eyePos == null) return false; double altitude = eyePos.getElevation(); return altitude >= this.minActiveAltitude && altitude <= this.maxActiveAltitude; } /** * @param dc the current draw context * @throws IllegalArgumentException if <code>dc</code> is null, or <code>dc</code>'s <code>Globe</code> or * <code>View</code> is null */ public void render(DrawContext dc) { if (!this.enabled) return; // Don't check for arg errors if we're disabled if (null == dc) { String message = Logging.getMessage("nullValue.DrawContextIsNull"); Logging.logger().severe(message); throw new IllegalStateException(message); } if (null == dc.getGlobe()) { String message = Logging.getMessage("layers.AbstractLayer.NoGlobeSpecifiedInDrawingContext"); Logging.logger().severe(message); throw new IllegalStateException(message); } if (null == dc.getView()) { String message = Logging.getMessage("layers.AbstractLayer.NoViewSpecifiedInDrawingContext"); Logging.logger().severe(message); throw new IllegalStateException(message); } if (!this.isLayerActive(dc)) return; if (!this.isLayerInView(dc)) return; this.doRender(dc); } public void pick(DrawContext dc, java.awt.Point point) { if (!this.enabled) return; // Don't check for arg errors if we're disabled if (null == dc) { String message = Logging.getMessage("nullValue.DrawContextIsNull"); Logging.logger().severe(message); throw new IllegalStateException(message); } if (null == dc.getGlobe()) { String message = Logging.getMessage("layers.AbstractLayer.NoGlobeSpecifiedInDrawingContext"); Logging.logger().severe(message); throw new IllegalStateException(message); } if (null == dc.getView()) { String message = Logging.getMessage("layers.AbstractLayer.NoViewSpecifiedInDrawingContext"); Logging.logger().severe(message); throw new IllegalStateException(message); } if (!this.isLayerActive(dc)) return; if (!this.isLayerInView(dc)) return; this.doPick(dc, point); } protected void doPick(DrawContext dc, java.awt.Point point) { // any state that could change the color needs to be disabled, such as GL_TEXTURE, GL_LIGHTING or GL_FOG. // re-draw with unique colors // store the object info in the selectable objects table // read the color under the coursor // use the color code as a key to retrieve a selected object from the selectable objects table // create an instance of the PickedObject and add to the dc via the dc.addPickedObject() method } public void dispose() // override if disposal is a supported operation { } protected abstract void doRender(DrawContext dc); public boolean isAtMaxResolution() { return this.isMultiResolution() ? false : true; } public boolean isMultiResolution() { return false; } public String getRestorableState() { return null; } public void restoreState(String stateInXml) { String message = Logging.getMessage("RestorableSupport.RestoreNotSupported"); Logging.logger().severe(message); throw new UnsupportedOperationException(message); } }